System of reusable software parts and methods of use

ABSTRACT

A system of reusable software parts for designing and constructing software components, applications and entire systems by assembly. Parts for generating events, shaping, distributing and controlling flows of events and other interactions are included. Also included are parts for handling synchronization and desynchronization of events and other interactions between parts, as well as parts for handling properties, parameterizing and serializing components, applications and systems. In addition, innovative adapter parts for interfacing parts that are not designed to work together are included. The system includes a dynamic container for software parts which supports integration of dynamically changing sets of parts into statically defined structures of parts. Other reusable parts for achieving such integration are also included.

BACKGROUND OF THE INVENTION

[0001] (1) Field of the Invention

[0002] The present invention is related to the field of object-orientedsoftware engineering, and, more specifically, to reusable softwarecomponents.

[0003] (2) Discussion of the Background of the Art

[0004] Over the last twenty years, the object paradigm, includingobject-oriented analysis, design, programming and testing, has becomethe predominant paradigm for building software systems. A wide varietyof methods, tools and techniques have been developed to support variousaspects of object-oriented software construction, from formal methodsfor analysis and design, through a number of object-oriented languages,component object models and object-oriented databases, to a number ofCASE systems and other tools that aim to automate one or more aspects ofthe development process.

[0005] With the maturation of the object paradigm, the focus has shiftedfrom methods for programming objects as abstract data types to methodsfor designing and building systems of interacting objects. As a result,methods and means for expressing and building structures of objects havebecome increasingly important. Object composition has emerged and israpidly gaining acceptance as a general and efficient way to expressstructural relationships between objects. New analysis and designmethods based on object composition have developed and most oldermethods have been extended to accommodate composition.

Composition Methods

[0006] The focus of object composition is to provide methods, tools andsystems that make it easy to create new objects by combining alreadyexisting objects. An excellent background explanation of analysis anddesign methodology based on object composition is contained in Real-timeObject-Oriented Modeling (ROOM) by Bran Selic et al., John Wiley & Sons,New York, in which Selic describes a method and a system for buildingcertain specialized types of software systems using object composition.

[0007] Another method for object composition is described inHOOD:Hierarchical Object-Oriented Design by Peter J. Robinson,Prentice-Hall, Hertfordshire, UK, 1 992, and “Creating Architectureswith Building Blocks” by Frank J. van der Linden and Jürgen K. Müller,IEEE Software, 12:6, November 1995, pp. 51-60.

[0008] Another method of building software components and systems bycomposition is described in a commonly assigned international patentapplication entitled “Apparatus, System and Method for Designing andConstructing Software Components and Systems as Assemblies ofIndependent Parts”, serial number PCT/US96/19675, filed Dec. 13, 1996and published Jun. 26, 1997, which is incorporated herein by referenceand referred to herein throughout as the “'675 application.”

[0009] Yet another method that unifies many pre-existing methods fordesign and analysis of object-oriented systems and has specificprovisions for object composition is described in the OMG UnifiedModeling Language Specification, version 1.3, June 1999, led by theObject Management Group, Inc., 492 Old Connecticut Path, Framingham,Mass. 01701.

Composition-based Development

[0010] Composition—building new objects out of existing objects—is thenatural way in which most technical systems are made. For example,mechanical systems are built by assembling together various mechanicalparts and electronic systems are built by assembling and connectingchips on printed circuit boards. But today, despite its many benefits,the use of composition to build software systems is quite limited,because supporting software design by composition has proven to beextremely difficult. Instead, inferior approaches to composition, whichwere limited and often hard-to-use, were taken because they were easierto support. Approaches such as single and multiple inheritance,aggregation, etc., have been widely used, resulting in fragile baseclasses, lack of reusability, overwhelming complexity, high rate ofdefects and failures.

[0011] Early composition-based systems include HOOD (see earlierreference), ObjecTime Developer by ObjecTime Limited (acquired byRational Software Corp.), Parts Workbench by Digitalk, and Parts forJava by ObjectShare, Inc. (acquired by Starbase Corp.). Each of thesesystems was targeted to solve a small subset of problems. None of themprovided a solution applicable to a broad range of software applicationtypes without impeding severely their performance. Specifically, use ofthese systems was primarily in (a) graphical user interfaces fordatabase applications and (b) high-end telecommunication equipment.

[0012] One system that supports composition for a broad range ofapplications without performance impediments is the system described inthe commonly assigned '675 application, with which it is possible tocreate new, custom functionality entirely by composition and without newprogram code. This system was commercialized in several products,including ClassMagic and DriverMagic, and has been used to create avariety of software components and applications ranging from graphicaluser interface property sheets, through Microsoft COM components, tovarious communications and device drivers.

[0013] Since 1996, other composition approaches have been attempted inresearch projects such as Espresso SCEDE by Faison Computing, Inc., andin commercial products such as Parts for Java by ParcPlace-Digitalk(later ObjectShare, Inc.), and Rational Rose RealTime by RationalSoftware Corp. None of these has been widely accepted or proven to beable to create commercial systems in a broad range of application areas.The only system known to the inventors that allows effective practicingof object composition in a wide area of commercial applications is thesystem described in the '675 application. The system and methoddescribed in the '675 application and its commercial and otherimplementations are referred to hereinafter as the “'675 system.”

Dynamically Changing Sets of Objects

[0014] Despite the apparent superiority of the system described in the'675 application, it, like all other composition-based systems describedabove failed to address adequately the important case in which part ofthe composed structure of objects needs to change dynamically, inresponse to some stimulus.

[0015] Except in trivial cases, most working, commercially viablesoftware components and applications require at least one element thatrequires dynamic changes. Examples include the ability to dynamicallycreate and destroy a number of sub-windows in a given window of agraphical user interface, and the ability to dynamically create anddestroy a connection object in a communications protocol stack when aconnection is established and dropped.

[0016] Although most of the above-described composition-based systems dohave the ability to modify structure dynamically, they do this throughsome amount of custom code and a violation of the composition view ofthe software system being built—in both cases essentially underminingthe composition approach and at least partially sacrificing itsadvantages.

[0017] In fact, one of the most common objections to thecomposition-based software design approach is that the structure ofsoftware applications is generally dynamic and changes all the time, andso the ability to compose statically new components is of very limiteduse. Furthermore, the implementation of the functionality required tohandle dynamic structures is quite complex, requires high professionalqualifications and is frequently a source of hard-to-find softwaredefects. As a result, the systematic and effective practice of softwaredesign and development by composition is seriously limited whenever theunderlying system does not provide a consistent, efficient, universaland easy-to-use support for dynamically changeable structures ofobjects.

Reusable Objects

[0018] Even if support for static composition and dynamic structures ofobjects is available, the use of composition is still difficult withouta significant number of readily available and easily reusable objectsfrom which new functionality can be composed.

[0019] Without such a library of reusable objects the compositionsystems mentioned above including the system described in the '675application is useful primarily for decomposing systems and applicationsduring design, and in fact, all these systems have been used mostly inthis way. With decomposition, the system designer uses acomposition-based system to express the required functionality in termsof subsystems and large-scale (thousands of lines of code) components,from which those systems are to be composed. This approach inevitablyleads to defining subsystems and components in a way that makes themquite specific to the particular application. Individual componentsdefined in such custom way then have to be custom implemented, which istypically achieved by either writing manually or generating unique codethat expresses the specific functionality of the component beingdeveloped.

[0020] Because of this absence of a substantial set of reusablecomponent objects from which new functionality can be easily composed,composition-based systems are essentially used in only two capacities:(a) as design automation aids, and (b) as integration tools orenvironments, with which individual components and subsystems designedfor composition but developed in the traditional way can be put togetherquickly.

[0021] In order to practice composition to the full extent implied bythe very name of this method and in a way that is similar to the waycomposition is used in all other technical disciplines, there is a needfor a set of well-defined, readily available and easily reusablecomponents, which is sufficiently robust to implement new andunanticipated application functionality, so that most, if not all ofthis new functionality can be built by composing these pre-existingobjects into new, application-specific structures.

[0022] The issue of software reusability has been addressed extensivelyover the last thirty years by a wide variety of approaches,technologies, and products. While the complete set of attemptedapproaches is virtually impossible to determine, most people skilled inthe art to which this invention pertains will recognize the followingfew forms as the only ones which have survived the trial of practice.These include function libraries, object-oriented application frameworksand template libraries, and finally, reusable components used inconjunction with component object models like Microsoft COM, CORBA andJava Beans.

[0023] Function libraries have been extremely successful in providingreusable functionality related to algorithms, computational problems andutility functions, such as string manipulation, image processing, andsimilar to them. However, attempts to use function libraries to packagereusable functionality that has to maintain a significant state betweenlibrary calls, or that needs to use a substantial number ofapplication-specific services in order to function, typically lead toexploding complexity of the library interface and increased difficultiesof use, as well as application-dependent implementations. An excellentexample of the inadequacy of the functional library approach to reusablefunctionality can be found in Microsoft Windows 98 Driver DevelopmentKit, in particular, in libraries related to kernel streaming and USBdriver support. These libraries, which provide less than half of therequired functionality of both kernel streaming and USB drivers, do soat the expense of defining hundreds of API calls, most of which arerequired in order to utilize the reusable functionality offered by thelibrary. As a result, attempts to actually use these libraries requirevery substantial expertise, and produce code that is unnecessarilycomplex, very difficult to debug, and almost impossible to separate fromthe library being used.

[0024] Application-specific object-oriented frameworks proliferatedduring the early to mid-nineties in an attempt to provide a solution tothe exploding complexity of GUI-based applications in desktop operatingsystems like Microsoft Windows and Mac OS. These frameworks providesubstantial support for functionality that is common among typicalwindows-based applications, such as menus, dialog boxes, status bars,common user interface controls, etc. They were, in fact, quitesuccessful in lowering the entry barrier to building such applicationsand migrating a lot of useful functionality from DOS to Windows. Furtheruse, however, showed that application-specific frameworks tend to bevery inflexible when it comes to the architecture of the application andmake it exceedingly difficult to build both new types of applicationsand applications that are substantially more complex than what wasenvisioned by the framework designers. It is not accidental that duringthe peak time of object-oriented framework acceptance, the major newWindows application that emerged—Visio from Shapeware, Inc., (nowMicrosoft Visio), was built entirely without the use of such frameworks.

[0025] Component object models, such as Microsoft COM and ActiveX, JavaBeans and, to a lesser extent, CORBA, were intended to provide asubstantially higher degree of reusability. These technologies providethe ability to develop binary components that can be shipped and usedsuccessfully without the need to know their internal implementations.Components defined in this way typically implement input interfaces,have some kind of a property mechanism and provide rudimentarymechanisms for binding outgoing interfaces, such as COM connectableobjects and the Java event delegation model.

[0026] And, indeed, component object models are considerably moresuccessful in providing foundations for software reuse. Today, hundredsof components are available from tens of different companies and can beused by millions of developers fairly easily.

[0027] Nevertheless, these component object technologies suffer from afundamental flaw which limits drastically their usability. The cost atwhich these technologies provide support for component boundaries,including incoming and outgoing interfaces and properties, is so high(in terms of both run-time overhead and development complexity) thatwhat ends up being packaged or implemented as a component is most oftena whole application subsystem consisting of tens of thousands of linesof code.

[0028] This kind of components can be reused very successfully insimilar applications which need all or most of the functionality thatthese components provide. Such components are, however, very hard toreuse in new types of applications, new operating environments, or whenthe functionality that needs to be implemented is not anticipated by thecomponent designer. The main reason for their limited reusability comesfrom the very fact that component boundaries are expensive and,therefore, developers are forced to use them sparingly. This results incomponents that combine many different functions, which are related toeach other only in the context of a specific class of applications.

[0029] As we have seen above, the type of reuse promoted by mostnon-trivial functional libraries and practically all applicationframeworks and existing component object models makes it relatively easyto implement variations of existing types of applications but makes itexceedingly difficult and expensive to innovate in both creating newtypes of applications, moving to new hardware and operatingenvironments, such as high-speed routers and other intelligent Internetequipment, and even to add new types of capabilities to existingapplications.

[0030] What is needed is a reuse paradigm that focuses on reusability innew and often unanticipated circumstances, allowing software designersto innovate and move to new markets without the tremendous expense ofbuilding software from scratch. The system described in the '675application provides a component object model that implements componentboundaries, including incoming and outgoing interfaces and propertymechanisms, in a way that can be supported at negligible developmentcost and runtime overhead. This fact, combined with the ability tocompose easily structures of interconnected objects, and build newobjects that are assembled entirely from pre-existing ones, creates thenecessary foundations for this type of reuse paradigm. Moreover, the'675 system, as well as most components built in conjunction with it,are easily portable to new operating systems, execution environments andhardware architectures.

SUMMARY OF THE INVENTION Advantages of the Invention

[0031] 1. It is therefore a first advantage of the present invention toprovide a set of easily reusable components that implement most of thefundamental functionality needed in a wide variety of softwareapplications and systems.

[0032] 2. It is a second advantage of the present invention to provide aset of reusable components that can be parameterized extensively withoutmodifying their implementation or requiring source code, thus achievingthe ability to modify and specialize their behavior to suit manydifferent specific purposes as required.

[0033] 3. Yet another advantage of the present invention is to provide aset of reusable components that can be combined easily into differentcomposition structures, in new and unanticipated ways, so that evenentirely new application requirements and functionality can be met bycombining mostly, if not only, pre-existing components.

[0034] 4. One other advantage of the present invention is to provide aset of reusable components that implements fundamental softwaremechanisms in a way that makes these mechanisms readily available tosystem developers, without requiring substantial understanding of theirimplementation.

[0035] 5. Yet another advantage of the present invention is that itprovides a set of reusable parts such that each of these partsimplements one well-defined mechanism or function in a way that allowsthis function to be combined with other functions in unanticipated ways.

[0036] 6. Still another advantage of the present invention is that itprovides a set of reusable parts defined so that most of these parts canbe implemented in a way that is independent from any specificapplication, so that the parts can be reused easily in new and widelydifferent application areas and domains.

[0037] 7. One other advantage of the present invention is that itprovides a set of reusable parts most of which can be implemented withno dependencies on any particular operating system, executionenvironment or hardware architecture, so that this set of parts and anysystems built using it can be easily ported to new operating systems,environments and hardware.

[0038] 8. Yet another advantage of the present invention is that itprovides a set of reusable parts that encapsulate large number ofinteractions with hardware and operating system environments, so thatcomponents and systems built using these parts have no inherentdependencies on the execution environment and can be moved to newoperating systems, environments and hardware with no modification.

[0039] 9. Yet another advantage of the present invention is that itprovides reusable parts that can initiate outgoing interactions inresponse to events that come from the outside of the designed system,thereby providing a uniform way for interfacing the functionality of thedesigned system with outside software or hardware.

[0040] 10. Still another advantage of the present invention is that itprovides reusable parts that can be inserted on a given connectionbetween other parts without modifying the semantics of this connection,and generate notifications whenever an interaction happens between thoseother parts, so that yet other parts can receive that notification andtake appropriate actions.

[0041] 11. Another advantage of the present invention is that itprovides reusable parts that convert one interface, logical or physicalcontract, or a set of incoming events, into another, thereby making iteasy to combine components that cannot be connected directly or wouldnot work if connected directly.

[0042] 12. Yet another advantage of the present invention is that itprovides reusable parts that can be used to connect one part to manyother parts even when the first part is not designed to interact withmore than one other part, and distribute the interactions between theparts so connected, so that various non-trivial structures of parts canbe easily composed.

[0043] 13. Still another advantage of the present invention is that itprovides reusable parts that can be connected to those outputs of otherparts which have no meaningful use within a specific design, so thatoutgoing interactions through those outputs do not cause malfunction ordisruption of the operation of the system and to provide a specific,pre-defined response to such outgoing operations.

[0044] 14. Another advantage of the present invention is that itprovides reusable parts that accept a flow of events or incominginteractions and produce an outgoing flow based on the history of theincoming interactions and a set of desired characteristics of the outputflow, so that an existing flow of events can be transformed into adesirable one.

[0045] 15. One other advantage of the present invention is that itprovides reusable parts that can be inserted on a given connectionbetween other parts without affecting the semantics of that connection,and provide observable indications of the interactions that transpirebetween those other parts.

[0046] 16. Yet another advantage of the preset invention is that itprovides reusable parts that store incoming events and forward them totheir outputs in response to specific other events or in a given threadof execution, thereby providing an easy way to desynchronize anddecouple interactions between other parts.

[0047] 17. Another advantage of the present invention is that itprovides reusable parts that convert incoming calls or synchronousrequests into pairs of asynchronous interactions consisting of requestsand replies, so that components that expect that their outgoing requestswill be handled synchronously can be combined easily with componentsthat process incoming requests asynchronously.

[0048] 18. Sill another advantage of the present invention is that itprovides reusable parts that make it possible to disable temporarily theflow of events on a given connection and accumulate incoming events inthis state until the flow is enabled again, so that other parts are notforced to accept and handle incoming events in states in which it is notdesirable to do so.

[0049] 19. One other advantage of the present invention is that itprovides reusable parts that allow other parts to process incoming flowsof events one event at a time by accumulating or otherwise holdinginteractions or requests that arrive while the first interaction is inprogress, so that those other parts are not forced to accept and processincoming interactions concurrently.

[0050] 20. One other advantage of the present invention is that itprovides reusable parts that expose the properties of other componentsand structures of components in the form of an interface that can beconnected to yet another component, so that that other component canaccess, enumerate and modify those properties.

[0051] 21. One other advantage of the present invention is that itprovides reusable parts that can serve as containers for variable setsof properties and their values, and expose those sets through aninterface that can be connected to other components so that thosecomponents can inspect and modify those property sets.

[0052] 22. One other advantage of the present invention is that itprovides reusable parts that can obtain variable sets of data valuesfrom outside storage and set those values as properties on structures ofother components, so that those structures of components can beparameterized to operate in a variety of pre-defined ways or inaccordance with previously saved persistent state.

[0053] 23. One other advantage of the present invention is that itprovides reusable parts that can enumerate persistent properties ofother components, structures of components, and entire applications, andstore the identifiers and values of those properties on externalstorage, so that the persistent state of those components, structures ofcomponents and applications can be preserved for future restoration.

[0054] 24. One other advantage of the present invention is that itprovides reusable parts that convert a connectable interface foraccessing properties into a set of events, and vice-versa, so thatcomponents that initiate operations on properties do not have to bedependent on the specific definition of this interface.

[0055] 25. One other advantage of the present invention is that itprovides reusable parts that set values of specific properties inresponse to incoming events so that event flows can be converted to dataoperations.

[0056] 26. Still another advantage of the present invention is toprovide a container for a dynamic set of software objects that presentsthat set as a single object.

[0057] 27. Another advantage of the present invention is to provide thedynamic container in a way that the single object which represents thedynamic set can be easily used in statically composed structures ofobjects.

[0058] 28. Still another advantage of the present invention is theprovision of the dynamic container in such a way that when the containedobjects have certain terminals and properties, the single object has thesame terminals and properties.

[0059] 29. Yet another advantage of the present invention is that thedynamic container further provides the ability to create and destroyinstances of objects, access their properties, connect and disconnectthem, and so on, in a uniform way defined by the container itself andnot requiring knowledge of the specific class of the contained objects.

[0060] 30. One other advantage of the present invention is that eachobject instance of the set of objects in the dynamic container can beindividually selected and addressed for any purpose by a uniqueidentifier assigned by the container.

[0061] 31. Another advantage of the present invention is that eachobject instance of the set of objects in the dynamic container can havea unique identifier associated with it, the identifier being assigned bythe software system outside of the container, so that each objectinstance can be individually selected and addressed for any purpose bythe unique identifier.

[0062] 32. Yet another advantage of the present invention is that theset of software objects in the dynamic container can be enumerated atany time so that software can determine what is the set of objectscontained at that time. 33. One other advantage of the present inventionis that a single implementation of the dynamic container is sufficientto handle any case where dynamic structures of objects are necessary.

[0063] 34. Another advantage of the present invention is the propertiesand terminals of the single object can be manipulated even when thedynamic container contains no objects (the container is empty).

[0064] 35. Yet another advantage of the present invention is that thedynamic container can be parameterized (configured) with a name of aclass of which instances are created, such that the software thatinitiates the creation of new object instances in the container canperform the initiation without knowledge of the class name.

[0065] 36. One other advantage of the present invention is that thedynamic container can, upon its own creation or another designatedevent, automatically create a desirable set of instances, freeing theoutside system from the need to control the initial set of objectinstances.

[0066] 37. Another advantage of the present invention is that aninstance of the dynamic container can contain other instances of thedynamic container.

[0067] 38. One other advantage of the present invention is that itprovides reusable parts that cause other parts to be created on apre-determined event, so that the newly created parts can handle thatevent and others related to it.

[0068] 39. Yet another advantage of the present invention is that itprovides reusable parts that control a dynamic container for partinstances and initiate the creation, destruction, parameterization andother preparations for normal operation of new part instances in thecontainer, whenever such new instances are needed, so that other partswill be able to use them without the need to control their life cycle,or even be aware that these parts are created dynamically.

[0069] 40. Another advantage of the present invention is that itprovides reusable parts that determine what part instances need to becreated and maintained in a dynamic set of instances, so that there willbe a proper set of these instances needed for the operation of a systemor component.

[0070] 41. Still another advantage of the present invention is that itprovides reusable parts that register part instances under apredetermined identifier, so that these instances can be accessed by apublicly known identifier, or included in other structures of parts byreference.

[0071] 42. One other advantage of the present invention is that itprovides reusable parts that make one or more classes of parts availablein executable code memory, relocated as may be required, and ready forinstantiation whenever such parts are needed, and remove them when nolonger needed, so that these parts don't have to be in that memory whennot needed.

[0072] 43. Yet another advantage of the present invention is that itprovides reusable parts that convert a set of events into a factoryinterface for creating and destroying objects in a dynamic set ofobjects (possibly, part instances), so that components that initiatesuch creation and destruction do not have to be dependent on thespecific definition of the factory interface.

[0073] 44. Another advantage of the present invention is that itprovides reusable parts that filter a set of operations on a factoryinterface for creating and destroying objects to either createdynamically new part instances or obtain identifiers to already existingpart instances, so that a new instance is created only when its servicesare first heeded, is made available to any part that requires suchservices, and can be destroyed when its services are no longer needed.

[0074] 45. Another advantage of the present invention is that it definesreusable interfaces and events that make it easy to build reusablesoftware parts and construct software systems by composition using suchparts.

[0075] To address the shortcomings of the background art, the presentinvention therefore provides:

[0076] A computer-implemented method in a computer system for designinga software system in which system at least a first object is createdarbitrarily earlier than a second object and the second object isautomatically connected to at least the first object, the methodcomprising the steps of:

[0077] creating the first object;

[0078] creating a first container object capable of holding at least oneother object of arbitrary object class;

[0079] defining at least a first template connection between the firstobject and the first container object;

[0080] creating the second object;

[0081] connecting the second object to the first object using the firsttemplate connection in which template the first container object isreplaced with the second object.

[0082] This method may alternatively be practiced wherein the step ofcreating the second object is performed by the first container object;or wherein the step of connecting the second object to the first objectis performed by the first container object; or wherein the step ofcreating the second object is performed by the first container objectand the step of connecting the second object to the first object isperformed by the first container object; or wherein connections betweenall objects are established between connection points on the objects; orwherein the first template connection is defined in a data structure.The invention also provides a system created using any one of theabove-listed methods.

[0083] Additionally, the invention provides a method for describingconnections between a plurality of objects in a software system in whichat least a first object of the plurality is created arbitrarily laterthan the remainder of the plurality, the method comprising the steps of:

[0084] defining at least a second object of the remainder;

[0085] defining a first container object which will be used as aplaceholder for defining connections between the first object and theremainder;

[0086] defining at least a first connection between the second objectand the first object by using the first container object in place of thefirst object.

[0087] Additionally, the invention provides a method for describingconnections between a first plurality of objects in a software systemand a second plurality of objects in the software system, the secondplurality being created arbitrarily later than the first plurality, themethod comprising the steps of:

[0088] defining at least a first object of the first plurality;

[0089] defining a first container object which will be used as aplaceholder for defining connections between the first object and eachobject of the second plurality;

[0090] defining at least a first connection to be created between thefirst object and each object of the second plurality as a connectionbetween the first object and the first container object.

[0091] Additionally, the invention provides, in a software system havinga plurality of objects, a container object comprising:

[0092] a first memory for keeping reference to at least a first objectof arbitrary object class;

[0093] a section of program code causing the first memory to be modifiedso that it will contain a first reference to a second object;

[0094] a section of program code accessing a data structure anddetermining that at least a first connection needs to be establishedbetween the second object and at least a third object;

[0095] a section of program code causing the first connection to beestablished.

[0096] The container object may further comprise a section of programcode causing the second object to be created.

[0097] Additionally, the invention provides, in a software system havinga plurality of objects, a container object comprising:

[0098] a memory for keeping at least one reference to a contained objectof arbitrary class;

[0099] a connection point for receiving requests to modify the set ofcontained objects;

[0100] at least one virtual connection point that accepts at least afirst connection to be established to the contained object, theacceptance occurring before the contained object is added to thecontained object; and

[0101] a section of program code that establishes the first connectionwhen the contained object is added to the container object.

[0102] In addition, the invention provides, in a software system havinga plurality of objects, a container object comprising:

[0103] a first memory for keeping at least one reference to a containedobject of arbitrary class;

[0104] a connection point for receiving requests to modify the set ofcontained objects;

[0105] at least one virtual property that accepts the value to be set ina first property on the contained object, the virtual property beingcapable of accepting values of a plurality of data types;

[0106] a section of program code that sets the first property on thecontained object to the accepted value when the contained object isadded to the contained object.

[0107] In a software system, the software system having a plurality ofobjects, a container object comprising:

[0108] a first memory for keeping a first plurality of contained objectsof arbitrary classes;

[0109] a second memory for keeping a second plurality of uniqueidentifiers, each identifier of the second plurality associated withexactly one object of the first plurality;

[0110] at least a first property, the first property being a secondproperty of a first object of the first plurality and the first propertybeing identified by a combined identifier produced by combining theassociated identifier of the first object and the identifier of thesecond property.

[0111] Moreover, each property immediately above may comprise aterminal, and in either embodiment, the second memory may be removed andcontained objects may be identified by identifiers assigned by thecontainer.

[0112] The invention further provides a container object class in asoftware system, the software system having a first plurality ofobjects, each object of the first plurality belonging to an objectclass, the container object class comprising:

[0113] means for holding a second plurality of contained objects, themeans being applicable to contained objects of any class;

[0114] means for changing the set of the contained objects, the meansbeing applicable to contained objects of any class;

[0115] means for presenting the plurality of contained objects as asingle object, the means being applicable to contained objects of anyclass.

[0116] It should be noted that the single object may comprise aninstance of the container object class, and the container object maycomprise an instance of the container object class.

[0117] The invention further provides, in a software system, thesoftware system having a plurality of objects, each object of theplurality of objects belonging to an object class, the software systemhaving means for building at least one structure of connected objectsand means of describing the structure of connected objects, a containerobject class comprising:

[0118] means for holding a plurality of contained objects, the meansbeing applicable to contained objects of any class;

[0119] means for changing the set of the contained objectsprogrammatically, the means being applicable to contained objects of anyclass;

[0120] means for presenting the plurality of contained objects as asingle object in the structure of connected objects, the means beingapplicable to contained objects of any class.

[0121] Also, the container object may comprise an instance of thecontainer object class.

[0122] The invention further provides, in a software system having atleast a first object and a second object, the first object having atleast one first connection point, the second object having at least onesecond connection point, the first connection point being used toestablish a first connection between the first connection point of thefirst object and the second connection point of the second object, andthe software system having means of requesting the establishment of aconnection between connection points, a container object comprising:

[0123] means for adding and removing the first object from thecontainer;

[0124] means for defining a third connection point on the containerobject;

[0125] means for transforming a requests for establishing of aconnection between the second connection point and the third connectionpoint into a request for establishing a connection between the secondconnection point and the first connection point.

[0126] The invention further provides that the system can include meansof identifying the first connection point using a first identifier, thecontainer object having the additional means to identify the thirdconnection point using the first identifier. Also, the software systemcan include means of identifying the first connection point using afirst identifier, the container object having the additional means toidentify the first object using a second identifier and the containerobject having the additional means to identify the third connectionpoint using a combination of the first identifier and the secondidentifier.

[0127] The invention further provides a container object in a softwaresystem, the software system having at least one first object and thecontainer object, the first object having at least one first property,the software system having means of requesting operations over the firstproperty, the container comprising:

[0128] means for adding and removing the first object from thecontainer;

[0129] means for defining a second property on the container object;

[0130] means for transforming a request for operations over the secondproperty into a request for operations over the first property.

[0131] The software system may also include means of identifying thefirst property using a first identifier, the container object having theadditional means to identify the second property using the firstidentifier; or means of identifying the first property using a firstidentifier, the container object having the additional means to identifythe first object using a second identifier and the container objecthaving the additional means to identify the second property using acombination of the first identifier and the second identifier. Thespecified means of the container may also be implemented independentlyof the class of the first object.

[0132] The invention further provides a container object in a softwaresystem, the software system having a plurality of objects, the softwaresystem having means for requesting operations over an object, thecontainer object comprising:

[0133] means for holding a plurality of contained objects;

[0134] means for changing the set of the contained objectsprogrammatically;

[0135] means for identifying each object of the contained objects by aseparate, unique identifier for each object;

[0136] means of handling requests for operations over any object of thecontained objects wherein the identifier is used to determine whichobject of the contained objects should handle the request.

[0137] Alternatively, the container may include additional means ofautomatically assigning the unique identifier to each object added tothe container. Also, the unique identifier may be assigned outside ofthe container, and the container may have the additional means ofassociating the unique identifier with each the contained object.

[0138] The invention further provides a method for caching andpropagating property values to a dynamic set of objects in a softwaresystem, the software system having a plurality of objects, each of theobjects having a plurality of properties, each the property having avalue and an identifier, the method comprising the steps of:

[0139] accepting a first request to modify the value of a first propertyon behalf of the dynamic set of objects as if the dynamic set of objectswere one object;

[0140] storing the value and identifier of the first property in a firstdata storage;

[0141] retrieving the value and identifier of the first property fromthe first data storage;

[0142] issuing a request to modify the value of the first property on afirst object of the dynamic set of objects, using the value andidentifier retrieved from the first data storage.

[0143] The invention further provides a method for caching andpropagating outgoing connections of a dynamic set of objects in asoftware system, the software system having a plurality of objects, thesoftware system having means for establishing connections between theobjects, the connections providing means for a first connected object tomake outgoing calls to a second connected object, the method comprisingthe steps of:

[0144] accepting the request to establish a first outgoing connectionbetween the dynamic set of objects and a first object, as if the dynamicset of objects were a single object;

[0145] storing a first data value necessary to effect the firstconnection in a first data storage;

[0146] retrieving the first data value from the first data storage;

[0147] issuing a request to establish a second connection between asecond object of the dynamic set and the first object, using the firstdata value retrieved from the first data storage.

[0148] Additionally, the invention provides a container object within asoftware system that utilizes either or both of the two methods forcaching described immediately above.

[0149] The invention further provides a container object in a softwaresystem, the software system having a plurality of objects, the softwaresystem having means for building at least one structure of connectedobjects, the software system having a first means of describing thestructure, the container object being a first object in the structure,the first object having a first connection to at least a second objectin the structure, the first connection being described by the firstmeans, the container comprising:

[0150] means for holding a plurality of contained objects;

[0151] means for changing the set of the contained objectsprogrammatically;

[0152] means for connecting each of the contained objects to the secondobject.

[0153] Alternatively, the above-described container object may includethe additional means of establishing all connections between thecontainer and other objects in the structure, the all connections beingdescribed by the first means, the additional means causing theestablishing of each of the all connections between each of thecontained objects and the other objects in the structure.

[0154] The invention further provides a container object in a softwaresystem, the software system having a plurality of objects, the softwaresystem having means of building at least one structure of connectedobjects, the software system having a first means of describing thestructure, the software system providing a second means of enumeratingall connections described by the first means, the container being afirst object in the structure, the container being connected to at leasta second object in the structure, the container comprising:

[0155] means for holding a plurality of contained objects;

[0156] means for changing the set of the contained objectsprogrammatically;

[0157] means for finding a first described connection between thecontainer and the second object;

[0158] means for establishing the first connection between a thirdobject contained in the container and the second object.

[0159] Alternatively, the container may establish connections between afirst connection point of the third object and a second connection pointof the second object.

[0160] The invention further provides a container object in a softwaresystem, the software system having a plurality of objects, the containerhaving a first connection to at least one object, the first connectionbeing described in a first data structure, the container comprising:

[0161] means for holding a plurality of contained objects;

[0162] means for changing the set of the contained objectsprogrammatically;

[0163] means for determining a first set of connections to beestablished for each object added to the set of contained objects basedon the set of connections described in the first data structure;

[0164] means for establishing the first set of connections.

[0165] Alternatively, the container may further comprise means fordissolving the first set of connections, or may further comprise:

[0166] means for remembering a second set of outgoing connections fromthe container to other objects

[0167] means for excluding the second set of connections from the firstset of connections

[0168] means for establishing the second set of outgoing connections foreach object added to the set of contained objects.

[0169] Alternatively, the container wherein may further comprise:

[0170] means for remembering properties set on the container;

[0171] means for setting remembered properties on each new object addedto the set of contained objects;

[0172] means for propagating properties set on the container to allobjects in the set of contained objects;

[0173] The invention further provides a container object in a softwaresystem, the software system containing a plurality of objects, thesoftware system having a first means to establish connections betweenconnection points of objects of the plurality, the first means providingthe ability to establish more than one connection to a first connectionpoint of a first object, the container object having a second connectionpoint connected to the first connection point of the first object, thecontainer comprising:

[0174] means for holding a plurality of contained objects;

[0175] means for changing the set of the contained objectsprogrammatically;

[0176] means for establishing a separate connection between a connectionpoint on each object of the plurality of contained objects and the firstconnection point of the first object.

[0177] Alternatively, the container may further comprise means forremembering properties set on the container.

[0178] The invention further provides a part for distributing eventsamong a plurality of parts, the part comprising:

[0179] a multiple cardinality input,

[0180] a multiple cardinality output,

[0181] means for recording references to parts that are connected to theoutput

[0182] means for forwarding events received on the input to each of theconnected objects to the output.

[0183] The invention further provides a part for distributing events andrequests between a plurality of other parts, the part comprising:

[0184] a first terminal for receiving calls;

[0185] a second terminal for sending calls out to a first connectedpart;

[0186] a third terminal for sending calls out to a second connectedpart;

[0187] means for choosing whether to send the received call through thesecond terminal or through the third terminal.

[0188] The invention further provides a part for distributing events andrequests between a plurality of other parts, the part comprising:

[0189] a first terminal for receiving calls;

[0190] a second terminal for sending calls out to a first connectedpart;

[0191] a third terminal for sending calls out to a second connectedpart;

[0192] means for choosing whether to first send the received callthrough the second terminal and then through the third terminal or tofirst send the received call through the third terminal and then throughthe second terminal.

[0193] The invention further provides a part for distributing events andrequests between a plurality of other parts, the part comprising:

[0194] a first terminal for receiving calls;

[0195] a second terminal for sending calls out to a first connectedpart;

[0196] a third terminal for sending calls out to a second connectedpart;

[0197] means for sending a first received call as a first call to thesecond terminal and then, based on value returned from the first call,choose whether or not to send the first received call as a second callto the third terminal.

[0198] The invention still further provides a method for desynchronizingevents and requests in a software system, the method comprising thesteps of:

[0199] storing the event in a memory;

[0200] receiving a pulse signal;

[0201] retrieving the event from the memory and continuing to processthe event in the execution context of the pulse signal.

[0202] The invention still further provides a part in a software system,the part comprising:

[0203] a first terminal for receiving calls;

[0204] a second terminal for sending calls out to a first connectedpart;

[0205] a third terminal for receiving a pulse call;

[0206] a memory for storing call information received from the firstterminal;

[0207] a section of program code that is executed when the part receivesthe pulse calls, the section retrieving the call information from thememory and sending a call out to the second terminal.

[0208] Alternatively, in the part described immediately above, thememory can hold call information for a plurality of calls, or the memorycan comprise a queue, or the memory can comprise a stack.

[0209] The invention still further provides a part in a software system,the part comprising:

[0210] a first terminal for receiving calls;

[0211] a second terminal for sending calls out to first connected part;

[0212] a memory for storing call information received from the firstterminal;

[0213] a means for obtaining execution context;

[0214] a section of program code that is executed in the executioncontext, the section retrieving the call information from the memory andsending a call out to the second terminal.

[0215] Alternatively, in the part described immediately above, the meansfor obtaining execution context may comprise a thread of execution in amultithreaded system, or the means for obtaining execution context maycomprise a timer callback, or the means for obtaining execution contextmay comprise a subordinate part. Also in the alternative, the means forobtaining execution context may comprise a subordinate part, thesubordinate part having a primary function of providing executioncontext for other parts.

[0216] The invention further provides a part in a software system, thepart comprising:

[0217] a first subordinate part for storing incoming data; and

[0218] a second subordinate part for generating execution context.

[0219] Alternatively, the part may further comprise a connection betweenthe first subordinate part and the second subordinate part.

[0220] The invention further provides a part in a software system, thepart comprising:

[0221] a first terminal for receiving an incoming request;

[0222] a second terminal for sending out an outgoing request;

[0223] a third terminal for receiving a request completion indication;

[0224] a synchronization object for blocking the thread in which theincoming request was received until the request completion indication isreceived.

[0225] Alternatively, the second terminal and the third terminal maycomprise one terminal.

[0226] The invention further provides a part in a software system, thepart comprising:

[0227] an input terminal for receiving calls of a first type;

[0228] an output terminal for sending calls of a second type;

[0229] means for converting calls of the first type to calls of thesecond type.

[0230] The invention further provides a part in a software system, thepart comprising:

[0231] an input terminal for receiving calls of a first type and sendingcalls of the first type;

[0232] an output terminal for receiving calls of a second type andsending calls of the second type;

[0233] means for converting calls of the first type to calls of thesecond type;

[0234] means for converting calls of the second type to calls of thefirst type.

[0235] Alternatively, any of the parts described herein may be furthercharacterized such that: the first type and the second type differ byphysical mechanism, or the first type and the second type differ bylogical contract.

[0236] The invention further provides a part in a software system, thepart comprising:

[0237] a first terminal for receiving a first request and sending asecond request;

[0238] a second terminal for sending the first request;

[0239] a third terminal for receiving the second request.

[0240] Alternatively, the part described immediately above may befurther characterized such that:

[0241] the first terminal is a bidirectional terminal;

[0242] the second terminal is an output terminal;

[0243] the third terminal is an input terminal.

[0244] The invention further provides a part in a software system, thepart comprising:

[0245] a first terminal for receiving calls;

[0246] a second terminal for sending out calls received on the firstterminal;

[0247] a third terminal for sending out calls whenever a call isreceived on the first terminal.

[0248] In the alternative, the part described above may be furthercharacterized such that the part further comprises a first property fordefining a criterion for selecting for which calls received on the firstterminal the part will send out calls through the third terminal, orsuch that the part further comprises a second property for configuringwhat call the part will send out the third terminal, or such that thepart further comprises a third property for configuring what call thepart will send out the third terminal before sending out a call receivedon the first terminal to the second terminal, or such that the partfurther comprises a third property for configuring what call the partwill send out the third terminal after sending out a call received onthe first terminal to the second terminal, or such that the part furthercomprises a third property for configuring whether a call out throughthe third terminal should be made before or after sending out a callreceived on the first terminal to the second terminal.

[0249] The invention further provides a part in a software system, thepart comprising:

[0250] a first terminal for receiving calls;

[0251] a second terminal for sending out calls received on the firstterminal;

[0252] a third terminal for sending out calls whenever a call sent outthe second terminal returns a pre-determined value.

[0253] Alternatively, the part described above may be furthercharacterized such that the part further comprises a property forconfiguring the pre-determined value, or such that the pre-determinedvalue indicates that the second call has failed, or such that thepre-determined value indicates that the second call has succeeded.

[0254] The invention further provides a part in a software system, thepart comprising:

[0255] a first terminal for receiving calls;

[0256] a second terminal for sending out calls received on the firstterminal;

[0257] a first property for configuring a first value;

[0258] a third terminal for sending out notification calls whenever acall sent out the second terminal returns a second value that matchesthe first value.

[0259] Alternatively, the part described above may further comprise asecond property for configuring whether the part will send out thenotification calls if the second value matches the first value or if thesecond value differs from the first value.

[0260] The invention further provides a part in a software system, thepart comprising:

[0261] a terminal for receiving calls of arbitrary logical contract;

[0262] a property for defining a return value.

[0263] Alternatively, he part described above may further comprise aproperty for configuring the logical contract for calls received on theterminal. Also, the part may be further characterized such that theterminal is an input terminal, or such that the terminal is abidirectional terminal and the part does not make calls out theterminal.

[0264] The invention further provides a part in a software system, thepart comprising:

[0265] a terminal for receiving a first call and a reference to a firstmemory;

[0266] a property for defining a return value;

[0267] a section of program code for freeing the first memory.

[0268] Alternatively, the part described above may be furthercharacterized such that the part further comprises means for determiningwhether the section of program code should be executed for the firstcall, or such that the part further comprises means for determiningwhether the section of program code should be executed for the firstcall based on a value contained in the first memory.

[0269] The invention further provides a part in a software system, thepart comprising:

[0270] a first terminal for receiving a first call;

[0271] a second terminal for sending out the first call;

[0272] means for extracting data from the first call;

[0273] means for formatting the extracted data as a first text;

[0274] means for sending out the first text.

[0275] Alternatively, the part described above may be furthercharacterized such that the means for sending out the first text is athird terminal, or the means for sending out the first text is a sectionof program code that invokes a function for displaying the first text ona console.

[0276] The invention further provides a first structure of connectedparts in a software system, the first structure comprising:

[0277] a factory part for determining when a new part should be created;

[0278] a container part for holding a first plurality of parts ofarbitrary part class;

[0279] a connection between the factory part and the container part.

[0280] In the alternative, the structure described above may be furthercharcterized such that:

[0281] the factory part has a first terminal;

[0282] the container part has a second terminal;

[0283] the connection is established between the first terminal and thesecond terminal.

[0284] Also, the structure may further comprise a demultiplexing parthaving a first terminal for receiving calls, a second terminal forsending out calls and means for selecting a part connected to the secondterminal, or may further comprise a plurality of connections, eachconnection established between the second terminal of the demultiplexingpart and a terminal of each part in the first plurality. Also, theconnection demultiplexing part and the factory part may comprise onepart.

[0285] In the alternative, the invention further provides a compositepart in a software system, the composite part comprising the structuredescribed above. In the alternative, the structure may further comprisean enumerator part for defining the set of parts in the first plurality.The structure may further comprise a connection between the enumeratorpart and the factory part. Also, the structure may be furthercharacterized such that the enumerator uses a data container fordefining the parts in the first plurality. Also, the enumerator maycomprise means for enumerating a set of peripheral devices connected toa computer system, or may further comprise a first property forconfiguring a limitation on the type of peripheral devices to beenumerated.

[0286] Alternatively, the structure may comprise a parameterizer partfor retrieving the value for at least one property to be set on eachpart of the first plurality. Also, the parameterizer part may retrievethe value from a data container, or the parameterizer part may use apersistent identifier to select the value among a set of values, or thestructure may further comprise a serializer part for saving the value ofat least on property of each part in the first plurality, or thestructure may further comprise a trigger part for initiating the savingof the value, or the structure may further comprise a parameterizer partfor retrieving the value for a first property to be set on each part ofthe first plurality and for saving the value of the first property.Also, in the alternative, the structure may be further characterizedsuch that the factory part determines whether to create a new part inthe first plurality or to use an existing part in the first pluralitybased a persistent identifier provided to the factory part, or such thatthe structure further comprises a loader part for bringing in memory aclass for a part to be created, or such that the structure furthercomprises:

[0287] a connection between the factory part and the loader part;

[0288] a connection between the loader part and the container part.

[0289] [structure: factory: genus] A part in a software system, the partcomprising:

[0290] a first terminal for receiving calls;

[0291] a second terminal for sending out calls received on the firstterminal;

[0292] a third terminal for sending out requests to create new parts;

[0293] means for selecting calls received on the first terminal forwhich the part sends out requests on the third terminal.

[0294] The invention further provides a method for designing access to ahardware component in a component-based software system, the methodcomprising the steps of:

[0295] designating a first software component for receiving interruptsfrom the hardware component;

[0296] designating a at least a second software component for accessinginput and output ports of the hardware component;

[0297] designating a third software component for handling interruptsreceived by the first software component;

[0298] designating a fourth software component for manipulating thehardware component;

[0299] connecting the first software component to the third softwarecomponent;

[0300] connecting the second software component to the fourth softwarecomponent.

[0301] In the alternative, the method described above may furthercomprise the step of connecting the third software component and thefourth software component, or may be further characterized such that thethird software component and the fourth software component are onecomponent.

[0302] The invention further provides a part in a software system, thepart comprising:

[0303] a first terminal for sending out calls;

[0304] a section of program code for receiving control when an interruptoccurs and sending out a call through the first terminal.

[0305] Alternatively, the part described above may further comprise aproperty for configuring which hardware interrupt vector among aplurality of hardware interrupt vectors the part should receive, or mayfurther comprise a section of program code for registering the part toreceive control when the interrupt occurs.

[0306] The invention further provides a part in a software system, thepart comprising:

[0307] a terminal for receiving requests to access at least one port ofa hardware component;

[0308] a property defining the base address of the port;

[0309] a section of code that accesses the port when a request isreceived on the first terminal.

[0310] Alternatively, the part described above may comprise amemory-mapped port, or an input-output port, or the requests may includea read request and a write request.

[0311] The invention further provides a structure of connected parts ina software system, the structure comprising:

[0312] an interrupt source part for receiving interrupt from a hardwarecomponent;

[0313] at least one port accessor part for accessing ports of thehardware component;

[0314] at least one controller part for controlling the hardwarecomponent.

[0315] In the alternative, the the structure described above may befurther characterized such that the controller part accesses thehardware component exclusively through the interrupt source part and theport accessor part, or such that the structure further comprises:

[0316] a connection between the interrupt source part and one of thecontroller parts;

[0317] a connection between one of the port accessor parts and one ofthe controller parts.

[0318] Alternatively, the invention further provides a composite part ina software system, the composite part containing any structure describedabove

[0319] The invention further provides a method for designing softwaresystem in which system at least a first object is created arbitrarilyearlier than a second object and the second object is automaticallyconnected to at least the first object, the method comprising the stepsof:

[0320] creating the first object;

[0321] creating a first container object capable of holding at least oneother object of arbitrary object class;

[0322] defining at least a first template connection between the firstobject and the first container object;

[0323] creating the second object;

[0324] connecting the second object to the first object using the firsttemplate connection in which template the first container object isreplaced with the second object

BRIEF DESCRIPTION OF THE DRAWINGS

[0325] The aforementioned features and advantages of the invention aswell as additional features and advantages thereof will be more clearlyunderstood hereinafter as a result of a detailed description of apreferred embodiment of the invention when taken in conjunction with thefollowing drawings in which:

[0326]FIG. 1 illustrates an event source by thread, DM_EST

[0327]FIG. 2 illustrates an event source, thread-based, DM_EVS

[0328]FIG. 3 illustrates an event source with DriverMagic pump, DM_ESP

[0329]FIG. 4 illustrates an event source by Windows message, DM_ESW

[0330]FIG. 5 illustrates a timer event source, DM_EVT

[0331]FIG. 6 illustrates a event source on interrupt, DM_IRQ

[0332]FIG. 7 illustrates a notifier, DM_NFY

[0333]FIG. 8 illustrates an advanced event notifier, DM_NFY2

[0334]FIG. 9 illustrates a notifier on status, DM_NFYS

[0335]FIG. 10 illustrates the internal structure of the DM_NFYS notifier

[0336]FIG. 11 illustrates a bi-directional notifier, DM_NFYB

[0337]FIG. 12 illustrates the internal structure of the DM_NFYB notifier

[0338]FIG. 13 illustrates a poly-to-drain adapter, DM_P2D

[0339]FIG. 14 illustrates a drain-to-poly adapter, DM_D2P

[0340]FIG. 15 illustrates a poly-to-drain adapter that provides theoperation bus as event bus, DM_NP2D

[0341]FIG. 16 illustrates a drain-to-poly adapter that uses the eventbus as operation bus, DM_ND2P

[0342]FIG. 17 illustrates a bidirectional drain-to-poly adapter, DM_BP2D

[0343]FIG. 18 illustrates an interface-to-interface adapter, DM_D2M

[0344]FIG. 19 illustrates an event set-to-event set adapter, DM_DIO2IRP

[0345]FIG. 20 illustrates a usage of the DM_DIO2IRP adapter

[0346]FIG. 21 illustrates another event set-to-event set adapter, DM_A2K

[0347]FIG. 22 illustrates a usage of the DM_A2K adapter

[0348]FIG. 23 illustrates an interface-to-event set adapter, DM_IES

[0349]FIG. 24 illustrates a usage of the DM_IES adapter

[0350]FIG. 25 illustrates a stateful adapter, DM_PLT

[0351]FIG. 26 illustrates the internal structure of the DM_PLT adapter

[0352]FIG. 27 illustrates an event recoder adapter, DM_ERC

[0353]FIG. 28 illustrates a status recoder adapter, DM_STX

[0354]FIG. 29 illustrates a usage of the DM_STX adapter

[0355]FIG. 30 illustrates another usage of the DM_STX adapter

[0356]FIG. 31 illustrates an asynchronous completer, DM_ACT

[0357]FIG. 32 illustrates a string formatter, DM_SFMT

[0358]FIG. 33 illustrates an event bus distributor, DM_EVB

[0359]FIG. 34 illustrates a notation used to reprsent the DM_EVB eventbus in diagrams

[0360]FIG. 35 illustrates a usage of the DM_EVB event bus

[0361]FIG. 36 illustrates a distributor for service, DM_DSV

[0362]FIG. 37 illustrates cascading of distributors

[0363]FIG. 38 illustrates an event replicator distributor, DM_RPL

[0364]FIG. 39 illustrates an event sequencer distributor, DM_SEQ

[0365]FIG. 40 illustrates an event sequencer distributor with thread,DM_SEQT

[0366]FIG. 41 illustrates the internal structure of the DM_SEQTdistributor

[0367]FIG. 42 illustrates a life-cycle sequencer, DM_LFS

[0368]FIG. 43 illustrates an event-controlled multiplexer distributor,DM_MUX

[0369]FIG. 44 illustrates a property-controlled switch distributor,DM_SWP

[0370]FIG. 45 illustrates a bidirectional property-controlled switchdistributor, DM_SWPB

[0371]FIG. 46 illustrates a connection demultiplexer distributor, ZP_CDM

[0372]FIG. 47 illustrates a bi-directional connection demultiplexerdistributor, ZP_CDMB

[0373]FIG. 48 illustrates a connection multiplexer-demultiplexerdistributor, ZP_CMX

[0374]FIG. 49 illustrates a usage of ZP_CMX for connecting multipleclients to a server

[0375]FIG. 50 illustrates another usage of ZP_CMX with dynamic structureof parts

[0376]FIG. 51 illustrates an event splitter filter distributor, DM_SPL

[0377]FIG. 52 illustrates a bidirectional event splitter filter, DM_BFL

[0378]FIG. 53 illustrates the internal structure of the DM_BFL filter

[0379]FIG. 54 illustrates a filter by integer value distributor, DM_IFLT

[0380]FIG. 55 illustrates a bi-directional filter by integer value,DM_IFLTB

[0381]FIG. 56 illustrates the internal structure of the DM_IFLTB filter

[0382]FIG. 57 illustrates a usage of the DM_IFLT filter

[0383]FIG. 58 illustrates a string filter distributor, DM_SFLT

[0384]FIG. 59 illustrates a string filter by four, DM_SFLT4

[0385]FIG. 60 illustrates a filter for Windows kernel mode input-outputrequest packet (IRP) events, DM_IRPFLT

[0386]FIG. 61 illustrates a bidirectional splitter distributor, DM_BSP

[0387]FIG. 62 illustrates a usage of the DM_BSP bi-directional slitter,for connecting two parts with unidirectional terminals to another partwith a bi-directional terminal

[0388]FIG. 63 illustrates a usage of the DM_BSP bi-directional splitter,for connecting a part with two uni-directional terminals to a part witha bi-directional terminal

[0389]FIG. 64 illustrates an interface splitter distributor, DM_DIS

[0390]FIG. 65 illustrates an idle generator by event distributor, DM_IEV

[0391]FIG. 66 illustrates a unidirectional drain stopper terminator,DM_STP

[0392]FIG. 67 illustrates a bidirectional drain stopper terminator,DM_BST

[0393]FIG. 68 illustrates a unidirectional polymorphic stopperterminator, DM_PST

[0394]FIG. 69 illustrates a bidirectional polymorphic stopperterminator, DM_PBS

[0395]FIG. 70 illustrates the internal structure of the DM_BSTterminator

[0396]FIG. 71 illustrates the internal structure of the DM_PSTterminator

[0397]FIG. 72 illustrates the internal structure of the DM_PBSterminator

[0398]FIG. 73 illustrates the universal stopper terminator, DM_UST

[0399]FIG. 74 illustrates the drain stopper terminator, DM_DST

[0400]FIG. 75 illustrates the internal structure of the DM_DSTterminator

[0401]FIG. 76 illustrates an event consolidator, DM_ECS

[0402]FIG. 77 illustrates a bidirectional event consolidator, DM_ECSB

[0403]FIG. 78 illustrates an indicator, DM_IND

[0404]FIG. 79 illustrates a call tracer indicator, DM_CTR

[0405]FIG. 80 illustrates a bus dumper indicator, DM_BSD

[0406]FIG. 81 illustrates a fundamental desynchronizer, DM_FDSY

[0407]FIG. 82 illustrates an event desynchronizer, DM_DSY

[0408]FIG. 83 illustrates a desynchronizer for requests, DM_DSYR

[0409]FIG. 84 illustrates the internal structure of the DM_DSYRdesynchronizer

[0410]FIG. 85 illustrates an event desynchronizer with external control(feed), DM_DWI

[0411]FIG. 86 illustrates an event desynchronizer with consolidateableexternal control, DM_DWI2

[0412]FIG. 87 illustrates the internal structure of the DM_DWI2desynchronizer

[0413]FIG. 88 illustrates desynchronizers with own thread, DM_DWT andDM_DOT

[0414]FIG. 89 illustrates the internal structure of the DM_DWTdesynchronizer

[0415]FIG. 90 illustrates the internal structure of the DM_DOTdesynchronizer

[0416]FIG. 91 illustrates a usage of the DM_DWT desynchronizer

[0417]FIG. 92 illustrates a usage of two DM_DWT desynchronizers to keepseparate the order of events from two event sources

[0418]FIG. 93 illustrates a usage of the DM_DOT desynchronizers

[0419]FIG. 94 illustrates desynchronizers with external thread (onDriverMagic pump), DM_DWP and DM_DOP

[0420]FIG. 95 illustrates the internal structure of the DM_DWPdesynchronizer

[0421]FIG. 96 illustrates the internal structure of the DM_DOPdesynchronizer

[0422]FIG. 97 illustrates desynchronizers on Windows messages, DM_DWWand DM_DOW

[0423]FIG. 98 illustrates the internal structure of the DM_DWWdesynchronizer

[0424]FIG. 99 illustrates the internal structure of the DM_DOWdesynchronizer

[0425]FIG. 100 illustrates a desynchronizer for requests with ownthread, DM_RDWT

[0426]FIG. 101 illustrates the internal structure of the DM_RDWTdesynchronizer

[0427]FIG. 102 illustrates a bidirectional resynchronizer, DM_RSB

[0428]FIG. 103 illustrates a resynchronizer, DM_RSY

[0429]FIG. 104 illustrates the internal structure of the DM_RSYresynchronizer

[0430]FIG. 105 illustrates a usage of the DM_RSY resynchronizer

[0431]FIG. 106 illustrates a usage of the DM_RSB resynchronizer

[0432]FIG. 107 illustrates a cascaded usage of resynchronizers

[0433]FIG. 108 illustrates a synchronous event buffer, DM_SEB

[0434]FIG. 109 illustrates the internal structure of the DM_SEB buffer

[0435]FIG. 110 illustrates an event buffer with postpone capability,DM_SEBP

[0436]FIG. 111 illustrates the internal structure of the DM_SEBP buffer

[0437]FIG. 112 illustrates a usage of th e DM_SEBP buffer

[0438]FIG. 113 illustrates an asymmetrical bidirectional event buffer,DM_ASB

[0439]FIG. 114 illustrates the internal structure of the DM_ASB buffer

[0440]FIG. 115 illustrates an asymmetrical buffer for requests, DM_ASBR2

[0441]FIG. 116 illustrates the internal structure of the DM_ASBR2 buffer

[0442]FIG. 117 illustrates the internal structure of the DM_ASBR buffer

[0443]FIG. 118 illustrates an event serializer, DM_ESL

[0444]FIG. 119 illustrates the internal structure of the DM_ESL eventserializer

[0445]FIG. 120 illustrates a request serializer, DM_RSL

[0446]FIG. 121 illustrates the internal structure of the DM_RSL requestserializer

[0447]FIG. 122 illustrates an IRP event popper, DM_EPP

[0448]FIG. 123 illustrates the internal structure of the DM_EPP eventpopper

[0449]FIG. 124 illustrates a property exposer, DM_PEX

[0450]FIG. 125 illustrates a virtual property container, DM_VPC

[0451]FIG. 126 illustrates a hierarchical repository, DM_REP

[0452]FIG. 127 Illustrates the binary structure of the DM_REP serializedimage

[0453]FIG. 128 illustrates a parameterizer from registry, DM_PRM

[0454]FIG. 129 illustrates a serializer to registry, DM_SER

[0455]FIG. 130 illustrates the internal structure of the DM_SERserializer

[0456]FIG. 131 illustrates an activation/deactivation adaptor, DM_SERADP

[0457]FIG. 132 illustrates an event to property interface converter,DM_E2P

[0458]FIG. 133 illustrates a property to event adapter, DM_P2E

[0459]FIG. 134 illustrates a property setter adapter, DM_PSET

[0460]FIG. 135 illustrates an eight property setters adapter, DM_PSET 8

[0461]FIG. 136 illustrates a graphical representation of a dynamiccontainer for parts

[0462]FIG. 137 illustrates types of connections between containedobjects and objects outside of the container that the preferredembodiment can support

[0463]FIG. 138 illustrates types of connections between containedobjects and objects outside of the container that the preferredembodiment does not support

[0464]FIG. 139 illustrates an example of a device driver architecturedesigned using a part array. The array is used to contain a dynamic setof part instances, one per each individual device that is serviced bythe driver

[0465]FIG. 140 illustrates a Windows WDM Plug-and-Play device driverfactory, DM_FAC

[0466]FIG. 141 illustrates a Windows NT device driver factory, DM_FAC

[0467]FIG. 142 illustrates a VxD device driver factory , DM_VXFAC

[0468]FIG. 143 illustrates a device enumerator on registry, DM_REN

[0469]FIG. 144 illustrates a PCI device enumerator , DM_REN

[0470]FIG. 145 illustrates a PCMCIA device enumerator, DM_PCEN

[0471]FIG. 146 illustrates a singleton registrar, DM_SGR

[0472]FIG. 147 illustrates a device stacker, DM_DSTK

[0473]FIG. 148 illustrates a create/bind factory interface adapter,DM_CBFAC

[0474]FIG. 149 illustrates a usage of the DM_CBFAC factory interfaceadapter

[0475]FIG. 150 illustrates an event to factory adapter, ZP_E2FAC

DETAILED DESCRIPTION OF THE INVENTION

[0476] The following definitions and references will assist the readerin comprehending the enclosed description of a preferred embodiment ofthe present invention.

[0477] The preferred embodiment is a software component object (part)that implements a dynamic container for other parts (hereinafter thePart Array or Array). The part is preferably used in conjunction withthe method and system described in the '675 application.

[0478] The terms ClassMagic and DriverMagic, used throughout thisdocument, refer to commercially available products incorporating theinventive System for Constructing Software Components and Systems asAssemblies of Independent Parts in general, and to certainimplementations of that System. Moreover, an implementation of theSystem is described in the following product manuals:

[0479] “Reference—C Language Binding—ClassMagic™ Object CompositionEngine”, Object Dynamics Corporation, August 1998, which is incorporatedherein in its entirety by reference;

[0480] “User Manual—User Manual, Tutorial and Part LibraryReference—DriverMagic Rapid Driver Development Kit”, Object DynamicsCorporation, August 1998, which is incorporated herein in its entiretyby reference;

[0481] “Advanced Part Library—Reference Manual”, version 1.32, ObjectDynamics Corporation, July 1999, which is incorporated herein in itsentirety by reference;

[0482] “WDM Driver Part Library—Reference Manual”, version 1.12, ObjectDynamics Corporation, July 1999, which is incorporated herein in itsentirety by reference;

[0483] “Windows NT Driver Part Library—Reference Manual”, version 1.05,Object Dynamics Corporation, April 1999, which is incorporated herein inits entirety by reference.

[0484] Appendix 1 describes preferred interfaces used by the partsdescribed herein.

[0485] Appendix 2 describes the preferred events used by the partsdescribed herein.

[0486] 1. Events

[0487] One inventive aspect of the present invention is the ability torepresent many of the interactions between different parts in a softwaresystem in a common, preferably polymorphic, way called event objects, orevents.

[0488] Events provide a simple method for associating a data structureor a block of data, such as a received buffer or a network frame, withan object that identifies this structure, its contents, or an operationrequested on it. Event objects can also identify the requireddistribution discipline for handling the event, ownership of the eventobject itself and the data structure associated with it, and otherattributes that may simplify the processing of the event or its deliveryto various parts of the system. Of particular significance is the factthat event objects defined as described above can be used to expressnotifications and requests that can be distributed and processed in anasynchronous fashion.

[0489] The word “event” is used herein most often in reference to eitheran event object or the act of passing of such object into or out of apart instance. Such passing preferably is done by invoking the “raise”operation defined by the I_DRAIN interface, with an event object as theoperation data bus. The I_DRAIN interface is a standard interface asinterfaces are described in the '675 application. It has only oneoperation, “raise”, and is intended for use with event objects. A largeportion of the parts described in this application are designed tooperate on events.

[0490] Also in this sense, “sending an event” refers to a part invokingits output I_DRAIN terminal and “receiving an event” refers to a part'sI_DRAIN input terminal being invoked.

[0491] 1.1. Event Objects

[0492] An event object is a memory object used to carry context data forrequests and for notifications. An event object may also be created anddestroyed in the context of a hardware interrupt and is the designatedcarrier for transferring data from interrupt sources into the normalflow of execution in systems based on the '675 system.

[0493] An event object preferably consists of a data buffer (referred toas the e,vent context data or event data) and the following “eventfields”:

[0494] event ID—an integer value that identifies the notification or therequest.

[0495] size—the size (in bytes) of the event data buffer.

[0496] attributes—an integer bit-mask value that defines eventattributes. Half of the bits in this field are standard attributes,which define whether the event is intended as a notification or as anasynchronous request and other characteristics related to the use of theevent's memory buffer. The other half is reserved as event-specific andis defined differently for each different event (or group of events).

[0497] status—this field is used with asynchronous requests andindicates the completion status of the request (see the AsynchronousRequests section below).

[0498] The data buffer pointer identifies the event object. Note thatthe “event fields” do not necessarily reside in the event data buffer,but are accessible by any part that has a pointer to the event databuffer.

[0499] The event objects are used as the operation data of the I_DRAINinterface's single operation—raise. This interface is intended for usewith events and there are many parts described in this application thatoperate on events.

[0500] The following two sections describe the use of events fornotifications and for asynchronous requests.

[0501] 1.2. Notifications

[0502] Notifications are “signals” that are generated by parts as anindication of a state change or the occurrence of an external event. The“recipient” of a notification is not expected to perform any specificaction and is always expected to return an OK status, except if for somereason it refuses to assume responsibility for the ownership of theevent object.

[0503] The events objects used to carry notifications are referred to as“self-owned” events because the ownership of the event object travelswith it, that is, a part that receives a notification either frees itwhen it is no longer needed or forwards it to one of its outputs.

[0504] 1.3. Asynchronous Requests

[0505] Using event objects as asynchronous requests provides a uniformway for implementing an essential mechanism of communication betweenparts:

[0506] the normal interface operations through which parts interact arein essence function calls and are synchronous, that is, control is notreturned to the part that requests the operation until it is completedand the completion status is conveyed to it as a return status from thecall.

[0507] the asynchronous requests (as the name implies) are asynchronous;control is returned immediately to the part that issues the request,regardless of whether the request is actually completed or not. Therequester is notified of the completion by a “callback”, which takes aform of invoking an incoming operation on one of its terminals,typically, but not necessarily, the same terminal through which theoriginal request was issued. The “callback” operation is preferablyinvoked with a pointer to the original event object that contained therequest itself. The “status” field of the event object conveys thecompletion status.

[0508] Many parts are designed to work with asynchronous requests. Note,however that most events originated by parts are not asynchronousrequests—they are notifications or synchronous requests. The “eventrecoder” (DM_ERC herein), in combination with other parts may be used totransform notifications into asynchronous requests.

[0509] The following special usage rules preferably apply to events thatare used as asynchronous requests:

[0510] 1. Requests are used on a symmetrical bi-directional I_DRAINconnection.

[0511] 2. Requests may be completed either synchronously orasynchronously.

[0512] 3. The originator of a request (the request ‘owner’) creates andowns the event object. No one except the ‘owner’ may destroy it or makeany assumptions about its origin.

[0513] 4. A special data field may be reserved in the request databuffer, referred to as “owner context”—this field is private to theowner of the request and may not be overwritten by recipients of therequest.

[0514] 5. A part that receives a request (through an I_DRAIN.raiseoperation) may:

[0515] a) Complete the request by returning any status except ST_PENDING(synchronous completion);

[0516] b) Retain a pointer to the event object and return ST_PENDING.This may be done only if the ‘attr’ field of the request has theCMEVT_A_ASYNC_CPLT bit set. In this case, using the retained pointer toexecute I_DRAIN.raise on the back channel of the terminal through whichthe original request was received completes the request. The part shouldstore the completion status in the “status” event field and set theCMEVT_A_COMPLETED bit in the “attributes” field before completing therequest in this manner.

[0517] 6. A part that receives a request may re-use the request's databuffer to issue one or more requests through one of its I_DRAINterminals, as long as this does not violate the rules specified above(i.e., the event object is not destroyed or the owner contextoverwritten and the request is eventually completed as specified above).

[0518] Since in most cases parts intended to process asynchronousrequests may expect to receive any number of them and have to executethem on a first-come-first-served basis, such parts are typicallyassembled using desynchronizers which preferably provide a queue for thepending requests and take care of setting the “status” field in thecompleted requests.

[0519] 1.4. The Notion of Event as Invocation of an Interface Operation

[0520] It is important to note that in many important cases, the act ofinvoking a given operation on an object interface, such as a v-tableinterface, can be considered an event to the large degree similar toevents described above. This is especially true in the case ofinterfaces which are defined as bus-based interfaces; in suchinterfaces, data arguments provided to the operation, as well as, datareturned by it, is exchanged by means of a data structure called bus.Typically, all operations of the same bus-based interface are defined toaccept one and the same bus structure.

[0521] Combining an identifier of the operation being requested with thebus data structure is logically equivalent to defining an event objectof the type described above. And, indeed, some of the inventive reusableparts described in this application use this mechanism to convert anarbitrary interface into a set of events or vice-versa.

[0522] The importance of this similarity between events and operationsin bus-based interfaces becomes apparent when one considers that itallows the application of many of the parts, design patterns andmechanisms for handling, distributing, desynchronizing and otherwiseprocessing flows of events, to any bus-based interface. In this manner,an outgoing interaction on a part that requires a specific bus-basedinterface can be distributed to multiple parts, desynchronized andprocessed in a different thread of execution, or even converted to anevent object. In all such cases, the outgoing operation can be passedthrough an arbitrarily complex structure of parts that shape and directthe flow of events and delivered to one or more parts that actuallyimplement the required operation of that interface, all through the useof reusable software parts.

[0523] 2. Event Flow Parts

[0524] Another inventive aspect of the present invention is the abilityto use reusable parts to facilitate, control and direct flows of eventsin a particular application or system. The existence of such parts,herein called “event flow parts”, provides numerous benefits. Forexample, it makes it possible to design and implement a wide variety ofapplication-specific event flow structures simply by combining instancesof reusable parts. In another example, one can implement advanced eventflow characteristics, such as distribution disciplines, one-to-many andmany-to-one relationships, intelligent event distribution based onstate, data contained in the event, or status returned by a specificpart, and many others, again, by interconnecting instances of reusableparts.

[0525] This section describes a number of inventive reusable event flowparts, which preferably form a basis for building most event flowstructures in software systems and applications built using objectcomposition.

[0526] 2.1. Event Sources

[0527] Event sources are parts that generate outgoing eventsspontaneously, as opposed to in response to receiving another event onan input. Usually, event sources generate output events in response tothings that happen outside of the scope of the structure of parts inwhich they are connected.

[0528] Event sources preferably have a bidirectional terminal, throughwhich they generate, or “fire”, outgoing events and receive controlevents, preferably “enable” and “disable”. In addition, event sourcespreferably define properties through which their operation can beparameterized.

[0529] When assembled in a structure with other parts, an event sourcepreferably remains inactive until it receives the first “enable” eventfrom one of these parts. After becoming enabled, the event source may(but not necessarily would) generate one or more outgoing events, whichare used by other parts to perform their operations. At some point intime or another, a part other than the source may generate a “disable”event. On receiving this event, the event source becomes disabled anddoes not generate outgoing events until enabled again. While practicalin many cases, the ability to enable and disable the event source fromoutside is not required for the advantageous operation of this type ofreusable parts.

[0530] Event sources vary primarily in the specific mechanism or causewhich triggers the generation of outgoing events. For example, aninterrupt event source, such as the DM_IRQ part described herein,receives hardware interrupts from a peripheral device and generatesevents for each received interrupt. In another example, a timer eventsource, such as the DM_EVT part described herein, creates an operatingsystem timer object, and generates outgoing events when that timerexpires or fires' periodically.

[0531] Another type of the inventive event source is a part thatcontrols an operating system or hardware-defined thread of execution andgenerates outgoing events in the execution context (e.g., stack,priority, security context, etc.), of that thread, so that other partsand structures of parts can operate within that context. An example ofsuch thread event source is the DM_EST part described herein.

[0532] As one skilled in the art to which the present invention pertainscan easily see, many other types of the inventive event source parts canbe defined and may be desirable in different classes of applications ordifferent operating environments. For example, the DM_ESW event sourcedescribed herein is an event source that is somewhat similar to a threadevent source but generates outgoing events in the execution contextassociated with a specific operating system window object, as this termis defined by the Microsoft Windows family of operating systems. Anotherexample, the DM_EVS event source described herein provides outgoingevents in a context of a specific thread which it owns and then onlyupon completion of an “overlapped” operating system call or upon thesignaling of a synchronization object, as those terms are defined in theMicrosoft Windows family of operating systems.

[0533] In many cases, it may be beneficial to define different eventsources, such as timer and thread, so that they have similar boundariesand interfaces, and may be interchanged in the design as required.However, this is a convenience and not necessarily a requirement.

[0534] Reusable event source parts have many advantages, among them theability to insulate the rest of the application from an important classof operating system or hardware-dependent interactions, in which theoutside environment invokes the application being designed. Anotheradvantage of using these parts is to separate the creation andmanagement of execution contexts, such as threads, as well as thedefinition of their characteristics, from the parts and structures ofparts that operate in these contexts.

[0535] 2.2. Notifiers

[0536] Notifiers are parts that can be inserted on a connection betweentwo other parts without affecting the semantics of the interactionsbetween those parts. Notifiers monitor those interactions and generatean outgoing event whenever an interaction that satisfies a specificcondition occurs.

[0537] Notifiers preferably have three terminals: “in”, “out” and “nfy”.The “in” and “out” terminals are used to connect the notifier to theparts whose interaction is to be monitored. The notifier generatesoutgoing events through the “nfy” terminal.

[0538] Notifiers preferably define properties through which thenotification conditions can be specified or modified, as well asproperties that define the characteristics of the outgoing notificationevent.

[0539] When assembled in a structure of parts, a notifier accepts callsthrough its “in” terminal, forwards them without modifications to the“out” terminal, and checks if the specified condition is satisfied bythat interaction. If the condition is true, the notifier creates anevent object as parameterized and sends it out through its “nfy”terminal. Conditions monitored by notifiers preferably include thepassing of an event object with specific characteristics, such asidentifier, attributes, etc., return of a specific status code from the“out” terminal, or the value of a specific field in the data bussatisfying a specific expression. In addition, notifiers may generatethe outgoing notification before, after or both before and afterforwarding the incoming event or interaction to the “out” terminal.

[0540] An example of a notifier which monitors for a specific eventidentifier is the inventive DM_NFY part described herein. Anotherexample of a notifier which monitors the return status of theinteraction is the inventive DM_NFYS part described herein.

[0541] Another type of notifier is the idle generator. Unlike othertypes of notifiers, idle generators produce series of outgoing events,preferably until one of these events returns a pre-defined completionstatus. An example of this type is the inventive DM_IEV part describedherein.

[0542] As will be understood by those skilled in the art to which thepresent invention pertains, many other types of the inventive notifierparts can be defined and may be desirable in different classes ofapplications or in different operating environments.

[0543] Reusable notifier parts have many advantages, among them theability to cause the execution of one or more auxiliary functions when acertain interaction takes place, without either of the partsparticipating in that interaction being responsible for causing theexecution, or even having to be aware that the execution takes place. Inthis manner, the inventive notifier parts described herein provide auniversal mechanism for extending the functionality of a given structureof parts in a backward-compatible way, as well as for synchronizing thestate of two or more parts or structures of parts in a way that does notintroduce undue coupling between them.

[0544] 2.3. Adapters

[0545] Adapters are parts the primary function of which is to convertone interface, set of events or logical contract, into another. Adaptersmake it possible to combine the functionality of two parts that are notdesigned to work directly together.

[0546] Adapters preferably have two terminals, “in” and “out”. The “in”terminal is used to receive incoming operations or events that belong toone of the interfaces; in response to these operations or events, theadapter issues outgoing operations or events, that comply with thesecond interface through its “out” terminal.

[0547] Adapters preferably define properties through which theiroperation can be modified as needed by the specific interfacetranslation that a given adapter implements.

[0548] Since the primary purpose of an adapter is to convert oneinterface into another, the number of possible and potentially usefuladapter parts is virtually unlimited. One advantageous type of inventiveadapters is an adapter that converts operations of any bus-based v-tableinterface into events. Examples of such adapters are the inventive partsDM_P2D and DM_P2D described herein, as well as the DM_D2P, DM_ND2P andDM_BD2P, which provide the opposite and combined conversions. Anothertype of inventive adapters converts one set of events complying to agiven protocol into another set, protocol or interface. Examples includethe inventive parts DM_A2K, DM_D102IRP, and DM_IES described herein. Yetanother advantageous type of inventive adapters include adapters thatmodify selected characteristics of events that pass through them; anexample of this type of adapter is the inventive part DM_ERC describedherein. One other advantageous type of inventive adapter is an adapterthat modifies the return status of an operation, such as the inventivepart DM_STX described herein.

[0549] Still another type of inventive adapter is the asynchronouscompleters. An asynchronous completer guarantees that certain requestsreceived on its “in” terminal will always complete asynchronously, evenwhen the part connected to its “out” terminal completes those requestsin a synchronous manner. An example of an asynchronous completer is theinventive part DM_ACT described herein.

[0550] Yet another type of inventive adapter is the string formattersthat can modify a text string, such as a name or URL path, or any otherdata value, in a passing event or data bus, according toparameterization that defines a specific transformation expression. Anexample of this type of adapter is the inventive part DM_SFMT describedherein.

[0551] Another, particularly important type of inventive adapter is thestateful adapters that maintain substantial state in betweeninteractions and preferably implement state machines that providecomplex conversions between widely differing protocols and interfaces.An example of this type of adapter is the inventive part DM_PLTdescribed herein.

[0552] 2.4. Distributors

[0553] Distributors are parts the main purpose of which is to forward,or distribute, interactions initiated by one part to zero or more otherparts. Distributors make it easy to implement structures of parts whichrequire interactions that cannot be represented directly by simpleone-to-one connections between terminals; such interactions includeone-to-many, many-to-one and many-to-many relationships.

[0554] Most types of distributors preferably have three terminals: “in”,“out1” and “out2”. They receive incoming interactions on their “in”terminal and forward them to “out1”, “out2” or both “out1” and “out2”,according to a specific distribution discipline. This group includes thefollowing types of distributors: (a) distributors for service, (b) eventreplicators, (c) sequencers, (d) filters, (e) bidirectional splitters,and (f) interface splitters.

[0555] Some other types of distributors preferably have an additionalcontrol terminal or property used to modify the distribution disciplinethey apply. This group includes the following types of distributors: (a)multiplexers controlled by event and (b) switches controlled by propertyvalue.

[0556] Yet other types of distributors preferably have two terminals: an“in” terminal through which they receive interactions, and a multiplecardinality “out” terminal. These types of distributors preferablydistribute interactions received on their “in” terminal among differentconnections established on their “out” terminal. This group includesconnection multiplexers and connection demultiplexers.

[0557] Other types of distributors preferably have one multiplecardinality, bi-directional terminal, to which other parts areconnected. These types of distributors, called buses, accept incominginteractions on any of the connections to that terminal, and distributethem among the same set of connections.

[0558] As will be understood by those skilled in the art to which thepresent invention pertains, many other types of the inventivedistributor parts can be defined and may be desirable in differentclasses of applications or in different operating environments.

[0559] The section below describes the preferred distributiondisciplines for a variety of distributor types.

[0560] Buses are distributors that implement many-to-many connections.They accept events from any of the parts connected to them, and forwardthem to all other parts, preferably excluding the one that originatedthat event. An example of a bus distributor is the inventive part DM_EVBdescribed herein.

[0561] Distributors for service attempt to submit the incominginteraction to both outputs, in sequence, until a certain condition,preferably related to the status returned from one or both of thoseoutputs, is met. When assembled in structures of parts, distributors forservice can be used for a variety of purposes, including, for example:(a) to sequence one and the same operation between multiple parts, (b)to submit the operation to several parts until one of them agrees toexecute it, and (c) to submit an operation to one part and then, basedon the status returned by it, to conditionally submit the same operationto another part. An example of a distributor for service is theinventive part DM_DSV described herein.

[0562] Event replicators are distributors that make a copy of anincoming event or operation bus and submit this copy to its “out2”output either before or after forwarding the original event or operationto “out1”. An example of an event replicator is the inventive partDM_RPL described herein.

[0563] Sequencers are a type of distributor that sequence an incomingoperation between their outputs until a certain return status isreceived, and preferably have the ability to sequence a differentoperation in reverse order. One advantageous use of sequencers is toenable a structure of parts, with the ability to disable back anyalready enabled part in case one of the parts fails the enable request.This guarantees that the state of all these parts will be coherent:either enabled or disabled. Examples of sequencers are the inventiveparts DM_SEQ, DM_SEQT and DM_LFS described herein.

[0564] Multiplexers, also known as switches, are a type of distributorthat maintain state and forward incoming interactions to one of theiroutputs depending on that state. This controlling state can be changedpreferably by an event received on a control terminal of themultiplexer, or by setting a specific value in a property of themultiplexer. Examples of multiplexers are the inventive parts DM_MUX,ZP_SWP and ZP_SWPB described herein.

[0565] Connection multiplexers and demultiplexers are a type ofdistributor that forward incoming interactions to one of the manypossible connections on their “out” terminal and vice-versa, Connectiondemultiplexers may preferably implement a variety of distributiondisciplines, including, for example, (a) by data value in the incomingbus which identifies the outgoing connection and (b) by state controlledin a manner similar to regular multiplexers described above. Connectionmultiplexers may preferably store an identification of the connectionfrom which the incoming interaction arrives into a specified data fieldin the bus before forwarding the interaction to the output. Examples ofconnection multiplexers and demultiplexers are the inventive partsDM_CDM, DM_CDMB and ZP_CMX described herein.

[0566] Filters are a type of distributors that forward incominginteractions to “out1” or “out2” based on a data value contained in thebus or on characteristics of the event object or the incoming operation.The conditions and/or expression that a filter evaluates to decide whichoutput to use are preferably specified through properties defined by thefilter. Examples of filters are the inventive parts DM_SPL, DM_BFL,DM_IFLT, DM_IFLTB, DM_SFLT, DM_SFLT4 and DM_IRPFLT described herein.

[0567] Bi-directional splitters are a type of distributor thatpreferably have three terminals: an input “in”, an output “out” and abidirectional terminal “bi”. These distributors forward operationsreceived on their “in” terminal to their “bi” terminal, and forwardoperations received on their “bi” terminal to their “out” terminal. Inthis manner, bi-directional splitters distribute the flow ofinteractions through a single, “bi”, terminal into two separateunidirectional flows that can be forwarded to two separate parts. Anexample of a bi-directional splitter is the inventive part DM_BSPdescribed herein.

[0568] Interface splitters are a type of distributor that forwarddifferent operations of one and the same input interface to differentoutputs. In this manner, interface splitters allow a set of operationsdefined by a single interface to be implemented by a plurality of parts.An example of an interface splitter is the inventive part DM_DISdescribed herein.

[0569] 2.5. Terminators

[0570] Terminators are parts that can be connected to those outputs ofother parts which have no meaningful use within a specific design, sothat outgoing interactions through those outputs do not causemalfunction or disruption of the operation of the system and preferablyprovide a specific, pre-defined response to such outgoing operations.

[0571] Terminators preferably have one terminal, “in”, implementedeither as an input terminal or as a bidirectional terminal. In addition,terminators preferably define a property through which the desiredreturn status can be parameterized.

[0572] Upon receiving an incoming event, a terminator preferablyexamines the event attributes, determines if the event object is to bedestroyed and the associated data structure is to be freed, and returnsthe specified return status.

[0573] Examples of terminators include the inventive parts DM_STP,DM_BST, DM_PST, DM_PBS, DM_UST and DM_DST described herein.

[0574] 2.6. Event Consolidators

[0575] Event consolidators are parts that provide “reference counting”behavior on a pair of complementary events, for example, “open” and“close”.

[0576] An event consolidator allows the first “open” event to passthrough, and consumes and counts any additional “open” events itreceives. In addition, it counts and consumes any “close” events untiltheir number reaches the number of “open” events. The last “close” eventis passed through.

[0577] Examples of event consolidators include the inventive partsDM_ECS and DM_ECSB described herein.

[0578] 2.7. Indicators

[0579] Indicators are parts that can be inserted on a given connectionbetween other parts without affecting the semantics of that connection,and provide observable indications of the interactions that transpirebetween those other parts, preferably in the form of human-readableoutput or debug notifications. The format of the output is preferablyspecified in properties defined by the indicator.

[0580] Examples of indicators include the inventive parts DM_IND, DM_CTRand DM_BSD described herein.

[0581] 3. Synchronization Parts

[0582] 3.1. Desynchronizers

[0583] Desynchronizers are parts that decouple the flow of control fromthe data flow. A simple desynchronizer preferably has input and outputterminals that work on the same logical contract, and a queue.

[0584] Whenever it receives an input operation, the desynchronizerpreferably collects the data arguments into a descriptor, or controlblock, enqueues the descriptor and returns immediately to the caller. Ona separate driving event, such as a timer, a thread or a system idleevent, the desynchronizer reads a descriptor from the head of the queueand invokes the respective operation on its output.

[0585] We define two categories of simple desynchronizers, with andwithout external drive, based on how (and when) they receive the drivingevents. Desynchronizers with external drive define a separate terminalthrough which another part, preferably an event source, may feed theevents. The others arrange to receive the events internally, usingoperating-system services such as timer callbacks or messages, or evenhardware interrupts.

[0586] Desynchronizers can be inserted in most connections where thedata flow is unidirectional. The other parties in the connection do nothave to support explicitly asynchronous connections—they remain unawareof the fact that the connections have been made asynchronous.

[0587] Examples of desynchronizers include the inventive parts DM_FDSY,DM_DSY, DM_DSYR, DM_DWI, DM_DWI2, DM_DWT, DM_DOT, DM_DWP, DM_DOP,DM_DWW, DM_DOW, and DM_RDWT described herein.

[0588] 3.2. Resynchronizers

[0589] Resynchronizers are parts that split a contract withbidirectional data flow into two—requests and replies. They arepreferably used to keep their clients blocked on an operation whileallowing the ultimate server connected to their output to performoperations in an event-driven manner for many clients. Theresynchronizer is responsible for blocking the incoming calls, forexample using operating system provided facilities in multi-threadedenvironments, until a reply for each respective call arrives.

[0590] Typical uses for resynchronizers include, for example, cases whenthe client part is a wrapper for a legacy component that implementslengthy operations, which involve issuing many outgoing calls. Using theresynchronizer, one can prevent such a part from blocking the system orthe server without having to make changes in either of them.

[0591] Examples of resynchronizers include the inventive parts DM_RSYand DM_RSYB described herein.

[0592] 3.3. Event Buffers

[0593] Event buffers are parts that forward incoming events andinteractions and also have memory to store one or more events or otherincoming interactions whenever they cannot be forwarded immediately.These parts make it possible to disable the flow of interaction betweenother parts temporarily without losing events that occur while the flowis disabled. Once the flow is re-enabled, the stored events andpreferably any new incoming events are forwarded as usual.

[0594] Event buffers preferably have three terminals: an input “in”, anoutput “out” and a control input “ctl ”. Incoming events arrive on the“in” terminal. If the buffer is enabled, it simply forwards the incomingevent to the “out” terminal. If the buffer is disabled, is stores theincoming event. The buffer is preferably enabled and disabled throughthe “ctl” terminal. Any events that are stored while the buffer isdisabled are preferably forwarded to the “out” terminal whenever thebuffer is re-enabled, or on another appropriate event.

[0595] One type of event buffers has a queue or other means for storingincoming events when the event buffer is disabled and then forwardingthem out in the same order in which they arrived. Examples of this typeof event buffers are the inventive parts DM_SEB, DM_ASB, DM_ASBR andDM_ASBR2 described herein.

[0596] Another type of event buffers also has the ability to temporarilystore, or “postpone”, particular events that are rejected by partsconnected to their “out” terminal while the buffer is enabled, andattempt to forward them again at a later time. These buffers preferablyforward any incoming events through their “out” terminal, and preferablyinterpret certain return statuses as an indication that the recipient isrejecting the event at that time. The buffers preferably store rejectedevents until they receive a “flush” event on their “ctl” terminal andattempt to resubmit them at that time. An example of this type of eventbuffers is the inventive part DM_SEBP described herein.

[0597] Event buffers preferably have properties for configuring themaximum number of stored events, the criteria for enabling and disablingthe flow, and other purposes.

[0598] One skilled in the art to which the present invention pertainscan easily see many other types of advantageous event buffers,including, but not limited to, buffers without a control input ordifferent control mechanism, buffers with different storage mechanisms,buffers with different conditions for buffering incoming events, and soon.

[0599] Event buffers make it possible to disable temporarily the flow ofevents on a given connection and accumulate certain or all incomingevents, so that other parts or structures of parts are not forced toprocess these events when it is not desirable to do so.

[0600] 3.4. Event Serializers

[0601] Event serializers are parts that forward incoming interactionsone by one and have means to hold further incoming interactions untilany pending interaction completes.

[0602] Event serializers preferably have an input terminal “in” forreceiving incoming events or interactions, an output terminal “out” forforwarding previously received events, and a state for tracking whetheran interaction that has been forwarded to “out” has not yet completed.If no interaction is pending, the serializer forwards an incominginteraction directly; while an interaction is pending, the serializerholds all other incoming events or interactions, for example, by storingthem in memory or by blocking the calling thread, until the pendinginteraction completes.

[0603] Examples of event serializers include the inventive parts DM_ESL,DM_RSL and DM_EPP described herein. One skilled in the art to which thepresent invention pertains can easily see many other types of eventserializers, for example, ones that use different mechanisms for storingheld interactions, and ones that use critical sections or othersynchronization objects to hold the calling thread.

[0604] Since event serializers pass incoming interactions one at a time,parts connected to their output do not have to accept or handle multipleinteractions concurrently.

[0605] 4. Property Space Support Parts

[0606] Another inventive aspect of the present invention is a set ofreusable parts that inspect, store and manipulate properties of otherparts and structures of parts through interfaces. These parts make itpossible to construct functionality needed to access properties byinterconnecting existing parts rather than writing code. It also makesit possible to set up the properties of a given part, component or evenwhole application to pre-configured values read from storage, as well asto preserve and restore the persistent state of that part, component orapplication.

[0607] 4.1. Property Exposers

[0608] Property exposers are parts that provide access to properties ofother parts through a terminal. They make it possible to constructfunctionality that manipulates those properties by interconnectingparts.

[0609] Property exposers preferably have an input terminal “prop”, thatexposes an interface or a set of events for requesting propertyoperations, such as get, set, check, enumerate, etc.

[0610] A property exposer preferably implements the functionalityrequired by the interface exposed through the “prop” terminal usingmeans defined by the underlying component or object model, such as the'675 system.

[0611] One type of property exposer provides access to the propertyspace of an assembly in which the instance of the property exposer iscreated. An example of this type of property exposer is the inventivepart DM_PEX described herein.

[0612] Other advantageous property exposers will be apparent to thoseskilled in the art to which the present invention pertains. By way ofexample, a property exposer may be configured with informationsufficient to identify a specific part instance, the properties of whichit is to expose.

[0613] 4.2. Property Containers

[0614] Property containers are parts that have storage for one or moreproperties and their respective values and make these propertiesavailable for access through an interface. They allow other parts tostore and examine various sets of properties.

[0615] Property containers preferably support arbitrary sets ofproperties and preferably include means for configuring those sets ofproperties. These means include, without limitation, properties on theproperty container itself, interfaces for defining the set ofproperties, data descriptors, etc.

[0616] One type of property container allows definition of the set ofstored properties through a terminal. This type of property containerpreferably has two terminals: a property factory “fac” for creating anddestroying properties in the container, and a property access terminal“prp” for accessing property values and enumerating the current set ofproperties in the container. An example of this type of propertycontainer is the inventive part DM_VPC described herein.

[0617] One skilled in the art to which the present invention pertainswill recognize that other advantageous types of property containers arepossible and easy to define. For example, a property container mayprovide access to the contained set of properties through any mechanismused to access properties of parts. Note that the inventive part DM_ARRdescribed herein can also be used in this capacity.

[0618] 4.3. Parameterizers

[0619] Parameterizers are parts that have means for obtaining a set ofproperty identifiers and values from storage and requesting property setoperations requests using those identifiers and values on their outputterminal. When combined preferably with a property exposer or othersimilar part, parameterizers can be used to configure a part or astructure of parts to operate in some desired way or to restore apreviously saved persistent state.

[0620] One type of parameterizer has an input terminal “in” forreceiving, and an output terminal “out”, for forwarding requests forproperty operations, as well as means for obtaining a set of propertyidentifiers and values from outside storage, such as registry, file orother media.

[0621] This type of parameterizer can process a property set requestreceived on its “in” terminal with a specific property identifier bytreating the value received with that request as a key that can be usedto identify a location in the outside storage, e.g., file name, memorylocation, registry key, etc. Upon receiving such trigger request, theparameterizer accesses that location to obtain one or more propertyidentifiers and their corresponding values from the storage, and emitsproperty set operations on its “out” terminal, with those identifiersand values. An example of this type of parameterizer is the inventivepart DM_PRM described herein.

[0622] 4.4. Serializers

[0623] Serializers are parts that obtain a set of properties that aredesignated as persistent and save them and their values into a storage.Serializers, in conjunction with property exposers, make it possible tosave an arbitrarily defined set of properties into external storage, sothat these properties can be restored later, preferably through the useof a parameterizer. The set of properties to be stored is defined by thepart or structure of parts whose properties are being serialized.

[0624] One type of serializer has an input terminal on which it acceptsa request to commence serialization, and an output terminal, throughwhich it collects the set of properties to be serialized. This type ofserializer preferably uses persistent storage to save the collectedproperties and values; such persistent storage is preferably a file or anon-volatile memory. An example of this type of serializer is theinventive part DM_SER described herein.

[0625] 4.5. Property Interface Adapters

[0626] Property interface adapters are parts that convert some interfaceinto a property interface or vice-versa.

[0627] Property interface adapters preferably have two terminals: “in”and “out”. A property interface is preferably the I_A_PROP interfacedescribed herein.

[0628] One type of property interface adapter converts one or moreevents into respective property operations and vice-versa. Propertyinterface adapters make it easy to use events to manipulate properties.Examples of this type of property interface adapter include theinventive parts DM_P2E and DM_E2P described herein.

[0629] One other type of property interface adapter preferably has oneor more properties for providing information that is missing from theincoming request but needs to be provided on the output request orvice-versa. Example of this type of property interface adapter includethe inventive parts DM_PSET and DM_PSET8.

[0630] Yet another type of property interface adapters may add advancedfunctionality. Examples include filtering out enumerated properties bysome template, replacing the identifiers of properties through atranslation table, converting property types to achieve typecompatibility, and many others.

[0631] 5. Dynamic Container for Parts

[0632] Dynamic containers for parts (hereinafter often referred as “partarray” without implication on how the parts are stored or accessed inthe container) are parts that preferably have memory for one or morecontained parts or references to those parts, and are capable ofpresenting the set of contained parts as a single part, the containeritself. This allows structures of parts to contain dynamically changingsubsets of those parts while still being able to describe the structurein a static way.

[0633] An example of a dynamic container for parts is the inventive partDM_ARR described herein.

[0634] 6. Dynamic Structure Support Parts

[0635] Dynamic structure support parts make it easy to buildfunctionality for manipulating a dynamically determined set of partinstances. They are reusable parts that make it easy to assemblestructures of parts that contain such a dynamically determined set ofinstances.

[0636] 6.1. Factories

[0637] Factories are parts that initiate the creation and otherpreparations for normal operation of dynamically created instances ofparts.

[0638] Factories preferably have at least two terminals: an “in” inputfor receiving events or other interactions on which the factory willinitiate a creation of one or more new instances, and a “fact” outputfor requesting that a new instance is created or otherwise added into acontainer connected to the “fact” output.

[0639] Factories preferably have another terminal, “out” for forwardingthe requests received on “in”. Factories may have additional terminals,such as terminals for parameterizing newly created instances, terminalsfor enumerating a set of instances to be created, for providing requeststo one or more of the dynamic instances, and others. Factoriespreferably can be configured with an identifier of a part class fromwhich the new instances will be created.

[0640] 6.2. Enumerators

[0641] Enumerators are parts that determine what part instances need tobe created in a dynamic set of part instances. Enumerators preferablyhave an “in” terminal for providing information about the dynamic set ofparts to be created and means for determining what that set is.

[0642] Enumerators may also have an additional terminal, such as aterminal for providing a set of properties to be configured on thedynamically created instances.

[0643] Examples of enumerators include the inventive parts DM_REN,DM_PEN and DM_PCEN described herein.

[0644] 6.3. Registrars

[0645] Registrars are parts that register part instances with someregistry.

[0646] Registrars preferably have a property for specifying anidentifier with which a part instance will be registered. One type ofregistrar registers the instance of the assembly in which it iscontained so that this instance can be used by reference in otherassemblies. An example of this type of registrar is the inventive partDM_SGR described herein.

[0647] Registrars of another type preferably have two properties: “id”for specifying an identifier to register, and “interface” for specifyingmeans for accessing a part instance. Such means may include functionpointer, identifier of object through which a part instance can beaccessed, etc. An example of this type of registrar is the inventivepart DM_DSTK described herein.

[0648] 6.4. Loaders

[0649] Loaders are parts that cause part classes to become available forcreation of instances when such instances are needed.

[0650] One type of loader preferably has two terminals: an “in” terminalof type I_A_FACT for receiving instance creation requests and an “out”terminal for forwarding requests received on “in”. Loaders of this typemonitor creation requests received on “in” and, when necessary, load theappropriate module that contains at least the part class an instance ofwhich is being requested, before forwarding the creation request to“out”.

[0651] An example of this type of loader is the inventive part DM_LDRdescribed herein.

[0652] Other advantageous types of loaders may use different mechanismsto determine when a part class needs to be loaded, or may performdifferent operation to cause the part class to become usable or betterto use. Such operations may include relocation in memory, bringing thepart class code into faster memory, etc. Such and other variations ofloaders will be apparent to those skilled in the art to which thepresent invention pertains.

[0653] 6.5. Factory Interface Adapters

[0654] Factory interface adapters are parts that convert some interfaceinto a factory interface or vice-versa. A factory interface ispreferably an interface similar to the I_A_FACT interface describedherein.

[0655] Factory interface adapters have at least two terminals: an “in”terminal for receiving requests or events and an “out” terminal forsending outgoing events or requests. Preferably, at least one of theterminals supports the factory interface.

[0656] One type of factory interface adapter is a part that makes itconvenient to use events to initiate factory interface operations. Thistype of adapter preferably has its “in” terminal for receiving eventsand its “out” terminal for requesting factory operations; it may alsohave properties for configuring what events cause what factoryoperations and additional information that is needed to perform thefactory operation, such as a class identifier. An example of this typeof factory interface adapter is the inventive part ZP_E2FAC describedherein.

[0657] Another type of factory interface adapter has both the “in” and“out” terminal supporting the factory interface and providing advancedfunctionality on the factory requests. An example of such an adapter isthe inventive part DM_CBFAC described herein.

Event Flow Parts Details Event Sources DM_EST—Event Source by Thread

[0658]FIG. 1 illustrates the boundary of the inventive DM_EST part.

[0659] DM_EST is an event source that generates both singular andperiodic events for a part connected to its evs terminal. DM_EST isarmed and disarmed via input operations on its evs terminal andgenerates events by invoking the fire output operation on the sameterminal. A user-defined context is passed to DM_EST when armed and ispassed back in the fire operation call when the time out period expires.

[0660] DM_EST allows itself to be armed only once. If DM_EST has notbeen armed to generate periodic events, it may be re-armed successfullyas soon as the event is generated; this includes being re-armed while inthe context of the fire operation call.

[0661] DM_EST may be disarmed at any time. Once disarmed, DM_EST willnever invoke the fire operation on evs until it is re-armed. The contextpassed to DM_EST when disarming it must match the context that waspassed with the arm operation.

[0662] DM_EST may be parameterized with default values to use whengenerating events and flags that control the use of the defaults andwhether or not DM_EST automatically arms itself when activated. Theseproperties can significantly simplify the use of DM_EST in that it ispossible to simply connect to and activate DM_EST to obtain a source ofevents.

[0663] 1. Boundary

[0664] 1.1. Terminals

[0665] Terminal “evs” with direction “Bidir” and contract In: I_EVS Out:I_EVS_R. Note: Synchronous, v-table, cardinality 1 Used to arm anddisarm the event source on the input and also to send the event on theoutput when the time period expires.

[0666] 1.2. Events and notifications

[0667] DM_EST has no incoming or outgoing events. The “event” generatedby DM_EST is a fire operation call defined in I_EVS_R; it is not anevent or notification passed via an I_DRAIN interface.

[0668] 1.3. Special Events, Frames, Commands or Verbs

[0669] None.

[0670] 1.4. Properties

[0671] Property “force_defaults” of type “UINT32”. Note: Boolean. IfTRUE, the time and continuous properties override the values passed inthe I_EVS bus. Default is FALSE.

[0672] Property “auto_arm” of type “UINT32”. Note: Boolean. If TRUE,DM_EST will automatically arm itself on activation. DM_EST will returnCMST_REFUSE on any evs.arm calls. The force defaults property must beset to TRUE for this property to be valid. If not, DM_EST will fail itsactivation. Default is FALSE.

[0673] Property “thread_priority” of type “UINT32”. Note: Threadpriority of DM_EST's worker thread. Default is THREAD_PRIORITY_NORMAL.

[0674] Property “time” of type “SINT32”. Note: Default time period inmilliseconds. Valid range is 1-0×7fffffff. When this time period expires(after DM_EST is armed), DM_EST will fire an event (by callingevs.fire). Default is −1.

[0675] Property “continuous” of type “UINT32”. Note: Boolean. If TRUEand DM_EST is armed, generate periodic events until disarmed. Default isTRUE.

[0676] 2. Encapsulated Interactions

[0677] DM_EST uses the following NT Kernel Mode APIs to control eventobjects and its worker thread:

[0678] KeInitializeEvent( )

[0679] KeSetEvent( )

[0680] KeClearEvent( )

[0681] PsCreateSystemThread( )

[0682] PsTerminateSystemThread( )

[0683] KeDelayExecutionThread( )

[0684] KeWaitForSingleObject( )

[0685] KeWaitForMultipleObjects( )

[0686] DM_EST uses the following Windows 95 Kernel Mode APIs to controlevent objects and its worker thread:

[0687] HeapAllocate( )

[0688] HeapFree( )

[0689] SignalID( )

[0690] BlockOnID( )

[0691] Get_System_Time( )

[0692] Time_Slice_Sleep( )

[0693] VWIN32_CreateRingOThread( )

[0694] Set_Thread_Win32_Pri( )

[0695] Set_Async_Time_Out( )

[0696] Create_Semaphore( )

[0697] Destroy_Semaphore( )

[0698] Signal_Semaphore_No_Switch( )

[0699] Wait_Semaphore( )

[0700] 3. Responsibilities p1 1. When armed with a time period, generatetimer events by calling evs.fire.

[0701] 2. Generate either one-shot timer events that require arming foreach or periodic timer events that require a single arm operation.

[0702] 3. Allow the re-arming/disarming of the event source while in thecontext of a evs.fire call.

[0703] 4. Allow disarming of single or periodic timer events. No eventsare to be sent out evs.fire at any time while DM_EST is disarmed (evenif periodic timer events are pending).

[0704] 4. Theory of Operation

[0705] 4.1. Mechanisms

Using a Separate Thread for Arm/disarm Requests

[0706] DM_EST uses a separate thread to arm/disarm the event source. Thethread waits for an arm or disarm request and acts appropriately. DM_ESTuses events to synchronize the execution and termination of the thread.Each instance of DM_EST maintains its own thread.

Arming the Event Source

[0707] When an arm request arrives (within the execution context of apart using DM_EST) the thread created by DM_EST is awakened and beginswaiting for the specified time period to expire usingKeDelayExecutionThread( ). When the time period has expired the threadwill fire an event through the evs terminal. The event source may bere-armed while in the execution context of a fire event. Upon returnfrom the fire event, the thread will re-arm the event source with theparameters passed with the arm request.

[0708] Note that arm requests fail with CMST_REFUSE if DM_EST wasparameterized to generate periodic events (continuous property is TRUE).

Disarming the Event Source

[0709] When a disarm request arrives (within the execution context of apart using DM_EST), the thread will disarm the event source (if armed).The event source will not fire again until it is re-armed.

[0710] The event source may be disarmed while in the execution contextof a fire event. Upon return from the fire event, the thread will disarmthe event source canceling any previous arm requests. The event sourcewill not fire again until it is re-armed.

Deactivation/Destruction of DM_EST

[0711] When the event source is destroyed, DM_EST waits for the workerthread to terminate. DM_EST will then free its resources and will notfire again until it is created, activated and armed.

[0712] DM_EST may be deactivated while in the execution context of afire event.

[0713] 4.2. Use Cases

Using the Event Source as a One-shot Timer

[0714] 1. DM_EST and Part A are created.

[0715] 2. Part A connects its evs terminal to DM_EST's evs terminal.

[0716] 3. Both parts are activated.

[0717] 4. Part A arms DM_EST passing a time period and a context.

[0718] 5. At some later point, the time period expires.

[0719] 6. DM_EST's worker thread calls Part A's fire operation throughits evs terminal passing the status CMST_OK and the context associatedwith the event (passed with the arm request).

[0720] 7. Part A does one of the following:

[0721] a. re-arms the event source—the event source is armed and willfire again when appropriate

[0722] b. continues execution—the event source is disarmed and will notfire again until Part A re-arms it at a later time

Using the Event Source as a Periodic Timer

[0723] 1. DM_EST and Part A are created.

[0724] 2. Part A connects its evs terminal to DM_EST's evs terminal.

[0725] 3. DM__EST is parameterized with the following:

[0726] a. force_defaults is TRUE

[0727] b. auto_arm is FALSE

[0728] c. time is set to some time interval for each event

[0729] d. continuous is TRUE

[0730] 4. Both parts are activated.

[0731] 5. Part A arms DM_EST passing a context.

[0732] 6. At some later point, the time period expires.

[0733] 7. DM_EST's worker thread calls Part A's fire operation throughits evs terminal passing the status CMST_OK and the context associatedwith the event-(passed with the arm request).

[0734] 8. Part A does one of the following:

[0735] c. disarms the event source—the event source is disarmed and willnot fire again until Part A re-arms it at a later time

[0736] d. continues execution—the event source will re-arm itself andwill fire again at a later time

[0737] 9. If the fire_delay property is not zero, DM_EST sleeps forfire_delay milliseconds before arming itself again for the next fireevent.

[0738] 10 .Steps 6-8 are executed many times as long as the event sourceremains armed.

Auto-arming the Event Source

[0739] 1. DM_EST and Part A are created.

[0740] 2. Part A connects its evs terminal to DM_EST's evs terminal.

[0741] 3. DM_EST is parameterized with the following:

[0742] a. force_defaults is TRUE

[0743] b. auto_arm is TRUE

[0744] c. time is set to some time interval for each event

[0745] d. continuous is TRUE

[0746] 4. Both parts are activated.

[0747] 5. At some later point, the time period expires.

[0748] 6. DM_EST's worker thread calls Part A's fire operation throughits evs terminal passing the status CMST_OK.

[0749] 7. Part A does one of the following:

[0750] a. disarms the event source—the event source is disarmed and willnot fire again until Part A re-arms it at a later time

[0751] b. continues execution—the event source will re-arm itself andwill fire again at a later time

[0752] 8. Steps 5-7 are executed many times as long as the event sourceremains armed.

Disarm Event Source to Terminate Firing

[0753] 1. DM_EST and Part A are created.

[0754] 2. Part A connects its evs terminal to DM_EST's evs terminal.

[0755] 3. Both parts are activated.

[0756] 4. Part A arms DM_EST passing a time period and a context.

[0757] 5. At some later point before the time period expires Part Adisarms the event source.

[0758] 6. The event source is disarmed and will not fire again until itis re-armed.

Deactivation/Destruction of DM_EST while the event source is armed

[0759] 1. DM_EST and Part A are created.

[0760] 2. Part A connects its evs terminal to DM_EST's evs terminal.

[0761] 3. Both parts are activated.

[0762] 4. Part A arms DM_EST passing a time period and a context.

[0763] 5. At some later point before the time period has expired, DM_ESTis deactivated (not necessarily by Part A).

[0764] 6. DM_EST signals the worker thread to stop waiting for thespecified time period to expire.

[0765] 7. DM_EST waits for its worker thread to terminate and releasesall its resources.

[0766] 8. DM_EST is destroyed.

[0767] DM_EVS—Event Source (thread-based)

[0768]FIG. 2 illustrates the boundary of the inventive DM_EVS part.DM_EVS is a generator of single and periodical events. DM_EVS uses aconjoint (bidirectional) interfaces I_EVS, output: I_EVS_R for thepurpose of arming, disarming and firing events. Parts connected to theevs terminal must implement the I_EVS_R interface in order to receiveevents from the event source.

[0769] The event source uses a separate thread to handle the arm anddisarm requests. Each instance of the event source maintains its ownthread. When the event source fires, it is always within the executioncontext of this thread.

[0770] The event source is armed by invoking the arm operation on itsevs terminal. DM_EVS can be armed with a Win32 synchronization objectand/or a timeout period (e.g. a timer can be specified by passing a NULLobject handle and a timeout period). When the synchronization objectmoves into a signaled state or the timeout period expires, the eventsource will invoke the fire operation through the evs terminal(I_EVS_R). A status is passed with the fire event that describes why theevent source fired.

[0771] A 32-bit context value must be passed with the arm request inorder to identify the fire event. When the fire operation is invoked onthe part connected to the evs terminal, this context is passed with theevent.

[0772] The event source may be armed, disarmed or deactivated at anytime (including within the execution context of a fire event). Once theevent source is disarmed, it will not fire again until it is re-armed ata later time.

[0773] The event source may only be armed once. If the event source isarmed more then once, DM_EVS returns CMST_NO_ROOM. The event source maybe re-armed after it was disarmed or after the event source fired.

[0774] This part is available only Win32 User Mode environment.

[0775] 5. Boundary

[0776] 5.1. Terminals

[0777] Terminal “evs” with direction “Bidir” and contract In: I_EVSOut:I_EVS_R. Note: v-table, single cardinality, synchronous Thisterminal is used to arm and disarm the event source. DM_EVS also usesevs to send an event when a synchronization object is signaled or atimeout occurs.

[0778] 5.2. Events and Notifications

[0779] None.

[0780] 5.3. Special Events, Frames, Commands or Verbs

[0781] None.

[0782] 5.4. Properties

[0783] Property “sync_lifecycle” of type “BOOL”. Note: If TRUE DM_EVSwaits for its worker thread to terminate on deactivation. Default isTRUE.

[0784] Property “sync_tout” of type “SINT32”. Note: This is the timeoutperiod used when DM_EVS is waiting for its worker thread to terminate;used only if sync_lifecycle is TRUE. Specified in milliseconds. Defaultis 1000 (1 second).

[0785] 6. Responsibilities

[0786] 1. Support event generation (firing) when a synchronizationobject gets signaled or a timeout period expires upon arrival.

[0787] 2. Support disarming the event source once it is armed.

[0788] 3. Support re-arming the event source in the execution context ofa fire event.

[0789] 7. Theory of Operation

[0790] 7.1. Main Data Structures

[0791] None.

[0792] 7.2. Mechanisms

Using a Separate Thread for Arm/disarm Requests

[0793] DM_EVS uses a separate thread to arm/disarm the event source. Thethread waits for an arm or disarm request and acts appropriately. Eachinstance of DM_EVS maintains its own thread.

Arming the Event Source: Within Client Execution Context

[0794] When an arm request arrives (within the execution context of apart using DM_EVS) the thread created by DM_EVS is awakened and beginswaiting on the synchronization object that was specified with the armrequest. When either the timeout is reached or the synchronizationobject is signaled, the thread will fire an event through the evsterminal.

Arming the Event Source: Within “Fire” Execution Context

[0795] The event source may be armed while in the execution context of afire event. Upon return from the fire event, the thread will re-arm theevent source with the parameters passed with the arm request.

Disarming the Event Source: Within Client Execution Context

[0796] When a disarm request arrives (within the execution context of apart using DM_EVS), the thread will disarm the event source (if armed).The event source will not fire again until it is re-armed.

Disarming the Event Source: within “Fire” Execution Context

[0797] The event source may be disarmed while in the execution contextof a fire event. Upon return from the fire event, the thread will disarmthe event source canceling any previous arm requests. The event sourcewill not fire again until it is re-armed.

Deactivation of DM_EVS: Within Client Execution Context

[0798] When the event source is deactivated, if the sync_lifecycleproperty is TRUE, DM_EVS will wait for the worker thread to terminate.DM_EVS will then free its resources and will not fire again until it isre-activated and re-armed.

[0799] If DM_EVS is deactivated while armed, DM_EVS will fire an eventwith the status CMST_CLEANUP in addition to the steps mentioned above.

Deactivation of DM_EVS: Within “Fire” Execution Context

[0800] The event source can be deactivated while in the executioncontext of a fire event. This should be avoided; the event source cannot properly cleanup its resources in this case. The event source willprint a message to the debug console and signal the worker thread todestroy iteself.

[0801] 7.3. Use Cases

Arming: Synchronization Object Signaled

[0802] 1. DM_EVS and Part A are created.

[0803] 2. Part A connects its evs terminal to DM_EVS's evs terminal.

[0804] 3. Both parts are activated.

[0805] 4. Part A creates an event synchronization object.

[0806] 5. Part A arms DM_EVS passing the event object, a timeout periodand a context associated with the event object.

[0807] 6. At some later point, the event object becomes signaled.

[0808] 7. DM_EVS's worker thread calls Part A's fire operation throughits evs terminal passing the status CMST_OK and the context associatedwith the event object (passed with the arm request).

[0809] 8. Part A does one of the following:

[0810] a. re-arms the event source—the event source is armed and willfire again when appropriate

[0811] b. continues execution—the event source is disarmed and will notfire again until Part A re-arms it

Arming: Synchronization Object Already in Signaled State

[0812] 1. DM_EVS and Part A are created.

[0813] 2. Part A connects its evs terminal to DM_EVS's evs terminal.

[0814] 3. Both parts are activated.

[0815] 4. Part A creates an event synchronization object.

[0816] 5. The event synchronization object enters a signaled state.

[0817] 6. Part A arms DM_EVS passing the event object, a timeout periodand a context associated with the event object.

[0818] 7. Immediately, DM_EVS's worker thread calls Part A's fireoperation through its evs terminal passing the status CMST_OK and thecontext associated with the event object (passed with the arm request).

[0819] 8. Part A does one of the following:

[0820] c. re-arms the event source—the event source is armed and willfire again when appropriate

[0821] d. continues execution—the event source is disarmed and will notfire again until Part A re-arms it

Arming: NULL Synchronization Object

[0822] 1. DM_EVS and Part A are created.

[0823] 2. Part A connects its evs terminal to DM_EVS's evs terminal.

[0824] 3. Both parts are activated.

[0825] 4. Part A arms DM_EVS passing a NULL object, a timeout period anda context associated with the NULL object.

[0826] 5. At some later point, the timeout period expires.

[0827] 6. DM_EVS's worker thread calls Part A's fire operation throughits evs terminal passing the status CMST_TIMEOUT and the contextassociated with the NULL object (passed with the arm request)

[0828] 7. Part A does one of the following:

[0829] e. re-arms the event source—the event source is armed and willfire again when appropriate

[0830] f. continues execution—the event source is disarmed and will notfire again until Part A re-arms it

Arming: Timeout Period on Synchronization Object Expired

[0831] 8. DM_EVS and Part A are created.

[0832] 9. Part A connects its evs terminal to DM_EVS's evs terminal.

[0833] 10. Both parts are activated.

[0834] 11. Part A creates an event synchronization object.

[0835] 12. Part A arms DM_EVS passing the event object, a timeout periodand a context associated with the event object.

[0836] 13. At some later point, the timeout period expires (thesynchronization object never was signaled).

[0837] 14. DM_EVS's worker thread calls Part A's fire operation throughits evs terminal passing the status CMST_TIMEOUT and the contextassociated with the synchronization object (passed with the armrequest).

[0838] 15. Part A does one of the following:

[0839] g. re-arms the event source—the event source is armed and willfire again when appropriate

[0840] h. continues execution—the event source is disarmed and will notfire again until Part A re-arms it

Arm Event Source: Sync. Object Owner Thread Terminates

[0841] 1. DM_EVS and Part A are created.

[0842] 2. Part A connects its evs terminal to DM_EVS's evs terminal.

[0843] 3. Both parts are activated.

[0844] 4. Part A creates a thread that creates a mutex synchronizationobject.

[0845] 5. Part A's thread arms DM_EVS passing the mutex object, atimeout period and a context associated with the mutex object.

[0846] 6. At some later point, the thread that owns the mutexterminates.

[0847] 7. DM_EVS's worker thread calls Part A's fire operation throughits evs terminal passing the status CMST_CANCELED and the contextassociated with the synchronization object (passed with the armrequest).

Disarm Event Source to Terminate Firing

[0848] 7. DM_EVS and Part A are created.

[0849] 8. Part A connects its evs terminal to DM_EVS's evs terminal.

[0850] 9. Both parts are activated.

[0851] 10. Part A creates an event synchronization object.

[0852] 11. Part A arms DM_EVS passing the event object, a timeout periodand a context associated with the event object.

[0853] 12. At some later point before the event object is signaled andbefore the timeout period has expired, Part A disarms the event source.

[0854] 13. The event source is disarmed and will not fire again until itis re-armed.

Deactivation of DM_EVS While the Event Source is Armed

[0855] 9. DM_EVS and Part A are created.

[0856] 10. Part A connects its evs terminal to DM_EVS's evs terminal.

[0857] 11. Both parts are activated.

[0858] 12. Part A creates an event synchronization object.

[0859] 13. Part A arms DM_EVS passing the event object, a timeout periodand a context associated with the event object.

[0860] 14. At some later point before the event object is signaled andbefore the timeout has expired, DM_EVS is deactivated (not necessarilyby Part A).

[0861] 15. DM_EVS signals the worker thread to stop waiting on the eventobject.

[0862] 16. DM_EVS's worker thread calls Part A's fire operation throughits evs terminal passing the status CMST_CLEANUP and the contextassociated with the event object (passed with the arm request).

[0863] 17. If the deactivation was in the execution context of a fireevent, DM_EVS prints a message to the debug console and becomesdeactivated without any cleanup.

[0864] 18. If the deactivation was in any other execution context:

[0865] a. If the sync_lifecycle property is TRUE, DM_EVS waits for itsworker thread to terminate.

[0866] b. DM_EVS releases all its resources and becomes deactivated.

DM_ESP—Event Source by DriverMagic Pump

[0867]FIG. 3 illustrates the boundary of the inventive DM_ESP part.

[0868] DM_ESP is an event source that generates both singular andcontinuous events by using the DriverMagic pump (queue). DM_ESP can bearmed and disarmed from any thread or restricted execution context (i.e.dispatch, interrupts). It can be armed to fire a single event per arming(single shot mode), or to keep firing until disarmed (continuous mode).

[0869] DM_ESP may be manually armed and disarmed, including from withinthe handler of the event it fired. Alternatively, DM_ESP can beparameterized to arm itself automatically upon activation, using themode specified in its properties; typically, auto arming is used withcontinuous mode.

[0870] DM_ESP can be armed only once; it must be disarmed before it canbe armed again. When arming DM_ESP, the caller can provide a contextvalue; DM_ESP passes this context value with every event it fires. Todisarm DM_ESP, the caller must pass the same context value.

[0871] 8. Boundary

[0872] 8.1. Terminals

[0873] Terminal “evs” with direction “Bidir” and contract In: I_EVS_Out:I_EVS_R. Note: Synchronous, v-table, cardinality 1 Used to arm anddisarm the event source on the input and also to send the event on theoutput.

[0874] 8.2. Events and notifications

[0875] DM_ESP has no incoming or outgoing events. The “event” generatedby DM_ESP is a fire operation call defined in I_EVS_R; it is not anevent or notification passed via an I_DRAIN interface.

[0876] 8.3. Special Events, Frames, Commands or Verbs

[0877] None.

[0878] 8.4. Properties

[0879] Property “force_defaults” of type “UINT32”. Note: Boolean. IfTRUE, the continuous property overrides the value passed in the I_EVSbus. Default is FALSE. Property “auto_arm” of type “UINT32”. Note:Boolean. If TRUE, DM_ESP will automatically arm itself on activation.DM_ESP will return CMST_REFUSE on any evs.arm or evs.disarm calls. Theforce_defaults property must be set to TRUE for this property to bevalid. If not, DM_ESP will fail its activation. Default is FALSE.Property “continuous” of type “UINT32”. Note: Boolean. If TRUE andDM_ESP is armed, generate continuous events until disarmed. Default isTRUE.

[0880] 9. Encapsulated Interactions

[0881] DM_ESP uses the DriverMagic pump as a source of events.

[0882] 10. Specification

[0883] 11. Responsibilities

[0884] 1. Generate either one-shot events that require arming for eachor continuous events that require a single arm operation.

[0885] 2. When armed, post a fire message to self. When the fire messageis dispatched to DM_ESP, fire an event through evs.fire. If incontinuous mode, re-post a fire message to self before returning fromthe message handler.

[0886] 3. Allow the re-arming/disarming of the event source while in thecontext of an evs.fire call.

[0887] 4. Allow disarming of single or continuous events. No events areto be sent out evs.fire at any time while DM_ESP is disarmed (even ifone or more fire messages are pending).

[0888] 12. Theory of Operation

[0889] 12.1. State Machine

[0890] None.

[0891] 12.2. Mechanisms

Arming the Event Source

[0892] When an arm request arrives (within the execution context of apart using DM_ESP) DM_ESP posts a fire message to itself. TheDriverMagic pump enqueues this message and dispatches it at a latertime. When the fire message handler is called, DM_ESP fires an eventthrough the evs terminal. If armed in continuous mode, DM_ESP re-posts afire message to itself before returning from the message handler.

[0893] The event source may be re-armed while in the execution contextof a fire event. Upon return from the fire event, DM_ESP re-arms theevent source with the parameters passed with the arm request.

[0894] Note that arm requests fail with CMST_REFUSE if DM_ESP is alreadyarmed. When DM_ESP is used in continuous mode and is armed once, DM_ESPis considered armed at all times until explicitly disarmed.

Disarming the Event Source

[0895] When a disarm request arrives (within the execution context of apart using DM_ESP), the event source becomes disarmed. The event sourcewill not fire again until it is re-armed.

[0896] The event source may be disarmed while in the execution contextof a fire event. Upon return from the fire event, DM_ESP disarms theevent source canceling any previous arm requests. The event source willnot fire again until it is re-armed.

Deactivation/Destruction of DM_ESP

[0897] When the event source is deactivated or destroyed, DM_ESP disarmsitself (if needed). DM_ESP will not fire again until it is created,activated and armed. DM_ESP may be deactivated while in the executioncontext of a fire event.

[0898] 12.3. Use Cases

Using DM_ESP for a One-shot Event Source

[0899] 1. DM_ESP and Part A are created.

[0900] 2. Part A connects its evs terminal to DM_ESP's evs terminal.

[0901] 3. Both parts are activated.

[0902] 4. Part A arms DM_ESP passing a context. DM_ESP posts a firemessage to itself.

[0903] 5. At some later point, the fire message is dispatched and itsmessage handler is called.

[0904] 6. DM_ESP calls Part A's fire operation through its evs terminalpassing the status CMST_OK and the context associated with the event(passed with the arm request).

[0905] 7. Part A does one of the following:

[0906] a. re-arms the event source—the event source is armed and willfire again when appropriate

[0907] b. continues execution—the event source is disarmed and will notfire again until Part A re-arms it at a later time

Using DM_ESP for a Continuous Source of Events

[0908] 1. DM_ESP and Part A are created.

[0909] 2. Part A connects its evs terminal to DM_ESP's evs terminal.

[0910] 3. DM_ESP is parameterized with the following:

[0911] a. force defaults is TRUE

[0912] b. auto_arm is FALSE

[0913] c. continuous is TRUE

[0914] 4. Both parts are activated.

[0915] 5. Part A arms DM_ESP passing a context.

[0916] 6. DM_ESP posts a fire message to itself.

[0917] 7. At some later point, the fire message is dispatched and itsmessage handler is called.

[0918] 8. DM_ESP calls Part A's fire operation through its evs terminalpassing the status CMST_OK and the context associated with the event(passed with the arm request).

[0919] 9. Part A does one of the following:

[0920] a. disarms the event source—the event source is disarmed and willnot fire again until Part A re-arms it at a later time

[0921] b. continues execution—the event source will re-arm itself andwill fire again at a later time

[0922] 10. Steps 6-9 are executed many times as long as the event sourceremains armed.

Auto-arming the Event Source

[0923] 1. DM_ESP and Part A are created.

[0924] 2. Part A connects its evs terminal to DM_ESP's evs terminal.

[0925] 3. DM_ESP is parameterized with the following:

[0926] a. force_defaults is TRUE

[0927] b. auto_arm is TRUE

[0928] c. continuous is TRUE

[0929] 4. Both parts are activated.

[0930] 5. DM_ESP posts a fire message to itself.

[0931] 6. At some later point, the fire message is dispatched and itsmessage handler is called.

[0932] 7. DM_ESP calls Part A's fire operation through its evs terminalpassing the status CMST_OK.

[0933] 8. Part A does one of the following:

[0934] a . disarms the event source—the event source is disarmed andwill not fire again until Part A re-arms it at a later time

[0935] b. continues execution—the event source will re-arm itself andwill fire again at a later time

[0936] 9. Steps 5-7 are executed many times as long as the event sourceremains armed.

Disarm Event Source to Terminate Firing

[0937] 1. DM_ESP and Part A are created.

[0938] 2. Part A connects its evs terminal to DM_ESP's evs terminal.

[0939] 3. Both parts are activated.

[0940] 4. Part A arms DM_ESP passing a context. DM_ESP posts a firemessage to itself.

[0941] 5. At some later point before the fire message handler is called,Part A disarms the event source.

[0942] 6. The event source is disarmed and will not fire again until itis re-armed.

Deactivation/Destruction of DM_ESP While the Event Source is Armed

[0943] 1. DM_ESP and Part A are created.

[0944] 2. Part A connects its evs terminal to DM_ESP's evs terminal.

[0945] 3. Both parts are activated.

[0946] 4. Part A arms DM_ESP passing a context. DM_ESP posts a firemessage to itself.

[0947] 5. At some later point before the fire message handler is called,DM_ESP is deactivated (not necessarily by Part A).

[0948] 6. DM_ESP is destroyed.

[0949] 13. Notes

[0950] 1. The events “fired” by DM_ESP are always in the executioncontext of the DriverMagic pump thread.

[0951] 2. DM_ESP's fire message handler is unguarded—the evs.fireoperation is never called within DM_ESP's guard.

DM_ESW—Event Source by Windows Message

[0952]FIG. 4 illustrates the boundary of the inventive DM_ESW part.

[0953] DM_ESW is an event source that can generate events in the contextof the thread in which DM_ESW was created. DM_ESW can be armed anddisarmed from any thread. It can be armed to fire a single event perarming (single shot mode), or to keep firing until disarmed (continuousmode). DM_ESW can delay the firing by a specified time interval from thearming; in continuous mode, subsequent firings are also delayed by thespecified time interval.

[0954] DM_ESW may be manually armed and disarmed, including from withinthe handler of the event it fired. Alternatively, DM_ESW can beparameterized to arm itself automatically upon activation, using themode and time interval specified in its properties; typically, autoarming is used with continuous mode.

[0955] DM_ESW can be armed only once; it must be disarmed before it canbe armed again. When arming DM_ESW, the caller can provide a contextvalue; DM_ESW passes this context value with every event it fires. Todisarm DM_ESW, the caller must pass the same context value.

[0956] To ensure that it fires events in the thread that created it,each instance of DM_ESW uses its own Win32 window to which it postsmessages; it fires the events from within the window message handler.Win32 guarantees that the messages are received in the thread thatcreated the window (which is the thread that created DM_ESW).

[0957] Note that for DM_ESW to operate properly, there are tworequirements coming from Win32:

[0958] a. the thread that created DM_ESW should be doing a message loop(i.e., call Win32 GetMessage or PeekMessage)—otherwise DM_ESW will notbe able to fire its events

[0959] b. DM_ESW should be destroyed in the same thread that created it;otherwise Win32 will not destroy the window and will leak a small amountresources.

[0960] DM_ESW is available only in the Win32 environment.

[0961] 14. Boundary

[0962] 14.1. Terminals

[0963] Terminal “evs” with direction “Bidir” and contract In: I_EVS_Out:I_EVS_R. Note: Synchronous, v-table, cardinality 1 Used to arm anddisarm the event source on the input and also to send the event on theoutput when the time period expires.

[0964] 14.2. Events and Notifications

[0965] DM_ESW has no incoming or outgoing events. The “event” generatedby DM_ESW is a fire operation call defined in I_EVS_R; it is not anevent or notification passed via an I_DRAIN interface.

[0966] 14.3. Special Events, Frames, Commands or Verbs

[0967] None.

[0968] 14.4. Properties

[0969] Property “force_defaults” of type “UINT32”. Note: Boolean. IfTRUE, the time and continuous properties override the values passed inthe I_EVS bus. Default is FALSE. Property “auto_arm” of type “UINT32”.Note: Boolean. If TRUE, DM_ESW will automatically arm itself onactivation. DM_ESW will return CMST_REFUSE on any evs.arm calls. Defaultis FALSE.

[0970] Property “time” of type “SINT32”. Note: Default time period inmilliseconds. Valid range is −1-0×7fffffff: −1: DM_ESW fires eventimmediately. In continuous mode it continuously fires events in a busyloop (in its window's message handler) until it is disarmed. 0: DM_ESWfires event immediately. In continuous mode it fires events bycontinuously posting messages to its event window until it is disarmed.all other values: when the time period expires (after DM_ESW is armed),DM_ESW will fire an event (by calling evs.fire). In continuous modeDM_ESW keeps firing events with this period until disarmed. Default is−1.

[0971] Property “continuous” of type “UINT32”. Note: Boolean. If TRUEand DM_ESW is armed, generate periodic events until disarmed. If FALSE,DM_ESW needs to be re-armed after each firing. Default is TRUE.

[0972] 15. Encapsulated Interactions

[0973] DM_ESW uses the following Win32 APIs to control its event windowand timers:

[0974] RegisterClass( )

[0975] UnregisterClass( )

[0976] CreateWindow( )

[0977] DestroyWindow( )

[0978] SetTimer( )

[0979] KillTimer( )

[0980] PostMessage( )

[0981] 16. Specification

[0982] 17. Responsibilities

[0983] 1. Register window class for event window only on first instanceconstrution of DM_ESW. Unregister window class on destruction of lastinstance.

[0984] 2. On construction, create a window in the context of the currentthread for event dispatching. On destruction destroy the window.

[0985] 3. When armed, either post a WM_USER message to the event windowor arm a Win32 timer for the specified time period.

[0986] 4. When the WM_USER or WM_TIMER message is received by the eventwindow message handler, fire an event through evs.fire (within the samethread that created DM_ESW).

[0987] 5. If time =−1 and armed in continous mode, after firing, enter abusy loop and fire events through evs.fire until disarmed.

[0988] 6. If time =0 and armed in continous mode, after firing, re-posta WM_USER message to the event window.

[0989] 7. If time >0 and armed in continous mode, after firing, arm aWin32 timer associated with the event window for the specified amount oftime.

[0990] 8. Allow the re-arming/disarming of the event source while in thecontext of a evs.fire call.

[0991] 9. Allow disarming of single or periodic timer events. No eventsare to be sent out evs.fire at any time while DM_ESW is disarmed.

[0992] 18. Theory of Operation

[0993] 18.1. Mechanisms

Generating Events Using a Separate Window

[0994] DM_ESW uses a window to generate events to its client. Eachinstance of DM_ESW maintains its own window.

[0995] On construction, DM_ESW creates a window in the current thread.When DM_ESW is armed it either posts a WM_USER message to the window orarms a Win32 timer (associated with the window). When the WM_USERmessage is received or the timer expires, the message handler fires anevent. If armed in continuous mode, the message handler will either posta new WM_USER message to the window, arm a Win32 timer or repeatedlyfire events until disarmed. See the next mechanism for more information.

[0996] DM_ESW destroys the window on destruction. DM_ESW must bedestroyed within the same thread that created it, otherwiseunpredictable results may occur (a Win32 limitation).

Arming the Event Source

[0997] When an arm request arrives (within the execution context of apart using DM_ESW), DM_ESW either posts a WM_USER message to its eventwindow or arms a Win32 timer (associated with the window). When theWM_USER message is received or the timer expires, the message handlerfires an event. If in continuous mode, depending on the time propertythe window's message handler does one of the following:

[0998] time is −1: DM_ESW enters a busy loop and continuously firesevents through the evs terminal until it is disarmed. During this time,no window messages for the current thread will be processed until DM_ESWis disarmed.

[0999] time is 0: DM_ESW re-posts a WM_USER message to its window. Whenthe WM_USER message is received, DM_ESW fires an event through the evsterminal as described above. This continues until DM_ESW is disarmed.

[1000] time is >0: DM_ESW arms a Win32 timer with the specified timeperiod and returns. When the time period expires, the message handlerreceives a WM_TIMER message and DM_ESW fires an event through the evsterminal.

[1001] The event source may be re-armed or disarmed while in theexecution context of a fire event.

[1002] Note: Arm requests fail with CMST_REFUSE if DM_ESW wasparameterized to auto arm itself on activation (auto_arm property isTRUE).

Disarming the Event Source

[1003] When a disarm request arrives (within the execution context of apart using DM_ESW), the event source is disarmed (if armed). The eventsource will not fire again until it is re-armed. The event source may bedisarmed while in the execution context of a fire event.

Deactivation/Destruction of DM_ESW

[1004] When the event source is destroyed, DM_ESW destroys its eventwindow. DM_ESW then frees its resources and will not fire again until itis created, activated and armed.

[1005] DM_ESW may be deactivated while in the execution context of afire event.

[1006] 18.2. Use Cases

Using the Event Source as a One-shot Timer

[1007] 1. DM_ESW and Part A are created.

[1008] 2. Part A connects its evs terminal to DM_ESW's evs terminal.

[1009] 3. Both parts are activated.

[1010] 4. Part A arms DM_ESW passing a time period >0 and a context.

[1011] 5. Part A begins running a message dispatch loop for its windows.

[1012] 6. At some later point, the time period expires.

[1013] 7. DM_ESW's message handler receives a WM_TIMER message and callsPart A's fire operation through its evs terminal passing the statusCMST_TIMEOUT and the context associated with the event (passed with thearm request).

[1014] 8. Part A does one of the following:

[1015] a. re-arms the event source—the event source is armed and willfire again when appropriate

[1016] b. continues execution—the event source is disarmed and will notfire again until Part A re-arms it at a later time

Using the Event Source as a Periodic Timer

[1017] 1. DM_ESW and Part A are created.

[1018] 2. Part A connects its evs terminal to DM_ESW's evs terminal.

[1019] 3. DM_ESW is parameterized with the following:

[1020] a. force_defaults is TRUE

[1021] b. auto_arm is FALSE

[1022] c. time is set to some time interval for each event

[1023] d. continuous is TRUE

[1024] 4. Both parts are activated.

[1025] 5. Part A arms DM_ESW passing a context.

[1026] 6. Part A begins running a message dispatch loop for its windows.

[1027] 7. At some later point, the time period expires.

[1028] 8. DM_ESW's message handler receives a WM_TIMER message and callsPart A's fire operation through its evs terminal passing the statusCMST_TIMEOUT and the context associated with the event (passed with thearm request).

[1029] 9. Part A does one of the following:

[1030] a. disarms the event source—the event source is disarmed and willnot fire again until Part A re-arms it at a later time

[1031] b. continues execution—the event source will re-arm itself andwill fire again at a later time

[1032] 10. Steps 6-8 are executed many times as long as the event sourceremains armed.

Auto-arming the Event Source

[1033] 9. DM_ESW and Part A are created.

[1034] 10. .Part A connects its evs terminal to DM_ESW's evs terminal.

[1035] 11. DM_ESW is parameterized with the following:

[1036] a. force_defaults is TRUE

[1037] b. auto_arm is TRUE

[1038] c. time is set to some time interval for each event

[1039] d. continuous is TRUE

[1040] 12. Both parts are activated.

[1041] 13. Part A begins running a message dispatch loop for itswindows.

[1042] 14. At some later point, the time period expires.

[1043] 15. DM_ESW's message handler receives a WM_TIMER message andcalls Part A's fire operation through its evs terminal passing thestatus CMST_TIMEOUT.

[1044] 16. Part A does one of the following:

[1045] a. disarms the event source—the event source is disarmed and willnot fire again until Part A re-arms it at a later time

[1046] b. continues execution—the event source will re-arm itself andwill fire again at a later time

[1047] 17. Steps 6-7 are executed many times as long as the event sourceremains armed.

Disarm Event Source to Terminate Firing

[1048] 1. DM_ESW and Part A are created.

[1049] 2. Part A connects its evs terminal to DM_ESW's evs terminal.

[1050] 3. Both parts are activated.

[1051] 4. Part A arms DM_ESW passing a time period and a context.

[1052] 5. Part A begins running a message dispatch loop for its windows.

[1053] 6. At some later point before the time period expires Part Adisarms the event source.

[1054] 7. The event source is disarmed and will not fire again until itis re-armed.

Deactivation/Destruction of DM_ESW While the Event Source is Armed

[1055] 1. DM_ESW and Part A are created.

[1056] 2. Part A connects its evs terminal to DM_ESW's evs terminal.

[1057] 3. Both parts are activated.

[1058] 4. Part A arms DM_ESW passing a time period and a context.

[1059] 5. Part A begins running a message dispatch loop for its windows.

[1060] 6. At some later point before the time period has expired, DM_ESWis deactivated (not necessarily by Part A).

[1061] 7. DM_ESW is destroyed.

[1062] 8. DM_ESW destroys the event window and completes destruction.

[1063] 19. Notes

[1064] 1. In order for DM_ESW to work correctly, the application thatcontains the part must provide a message dispatch loop as defined byWindows. This allows the messages for an application to be dispatched tothe appropriate window. Please see the Win32 documentation for moreinformation.

[1065] 2. As Win32 requires that windows be destroyed in the same threadin which they were created, DM_ESW also must be destroyed in the samethread in which it was created. Failure to do so will typically fail todestroy the window.

[1066] 3. When DM_ESW is used in continuous mode to fire events in abusy loop (time=−1), an attempt to disarm and re-arm the event sourcewhile in the context of a fire event has no effect on the event source.DM_ESW will continue to fire events in a busy loop. This is the intendedbehavior.

DM_EVT—Timer Event Source

[1067]FIG. 5 illustrates the boundary of the inventive DM_EVT part.

[1068] DM_EVT is a timer event source that generates both singular andperiodic timer events for a part connected to its evs terminal. DM_EVTis armed and disarmed via input operations on its evs terminal andgenerates timer events by invoking the fire output operation on the sameterminal. A user defined context is passed to DM_EVT when armed and ispassed back in the fire operation call when the time out period expires.

[1069] DM_EVT allows itself to be armed only once. If DM_EVT has notbeen armed to generate periodic timer events, it may be re-armedsuccessfully as soon as the timer event is generated; this includesbeing re-armed while in the context of the fire operation call.

[1070] DM_EVT may be disarmed at any time. Once disarmed, DM_EVT willnever invoke the fire operation on evs until it is re-armed. The contextpassed to DM_EVT when disarming it must match the context that waspassed with the arm operation.

[1071] DM_EVT may be parameterized with default values to use whengenerating events and flags that control the use of the defaults andwhether or not DM_EVT automatically arms itself when activated. Theseproperties can significantly simplify the use of DM_EVT in that it ispossible to simply connect to and activate DM_EVT to obtain a source ofevents.

[1072] DM_EVT is boundary compatible with the DM_EVS part.

[1073] This part is only available in Windows NT/95/98 Kernel Modeenvironments.

[1074] 20. Boundary

[1075] 20.1. Terminals

[1076] Terminal “evs” with direction “Bidir” and contract In: I_EVS_Out:I_EVS_R. Note: Used to arm and disarm the event source on the input andto send the timer event on the output when the time period expires.

[1077] 20.2. Events and Notifications

[1078] DM_EVT has no incoming or outgoing events. The timer “event”generated by DM_EVT is a fire operation call defined in I_EVS_R; it isnot an event or notification passed via an I_DRAIN interface.

[1079] 20.3. Special Events, Frames, Commands or Verbs

[1080] None.

[1081] 20.4. Properties

[1082] Property “force_defaults” of type “UINT32”. Note: Boolean. Ifnon-zero, the time and continuous properties override the values passedin the I_EVS bus. Default is FALSE.

[1083] Property “auto_arm” of type “UINT32”. Note: Boolean. If non-zero,DM_EVT will automatically arm itself on activation. DM_EVT will returnCMST_REFUSE when on any call evs.arm call. The force_defaults propertymust be set to TRUE for this property to be valid. If not, DM_EVT willfail its activation. Default is FALSE.

[1084] Property “time” of type “SINT32”. Note: Default time period inmilliseconds. Valid range is 1-0×7fffffff. Default is 500.

[1085] Property “continuous” of type “UINT32”. Note: Boolean. Ifnon-zero and DM_EVT is armed, generate periodic events until disarmed.Default is FALSE.

[1086] 21. Encapsulated Interactions

[1087] 21.1. Windows NT Kernel Mode

[1088] DM_EVT uses KeInitializeTimerEx( ) and KeInitializeDpc( ) toinitialize a timer object and a deferred procedure. DM_EVT utilizes thekernel-mode services KeSetTimerEx( ) and KeCancelTimer( ) to generateand cancel timer events.

[1089] DM_EVT does not create any threads.

[1090] 21.2. Windows 95/98 Kernel Mode

[1091] DM_EVT utilizes the VMM services Set_Async_Time_Out( ) andCancel_Time_Out( ) to generate and cancel timer events.

[1092] DM_EVT does not create any threads.

[1093] 22. Specification

[1094] 23. Responsibilities

[1095] 5. When armed with a time period, generate timer events bycalling evs.fire.

[1096] 6. Generate either one-shot timer events that require arming foreach or periodic timer events that require a single arm operation.

[1097] 7. Allow the re-arming of the timer event source while in thecontext of a evs.fire call.

[1098] 8. Allow disarming of single or periodic timer events. No eventsare to be sent out evs.fire at any time while DM_EVT is disarmed (evenif periodic timer events are pending).

[1099] 24. Theory of Operation

[1100] 24.1. State Machine

[1101] None.

[1102] 24.2. Data Structures Used in Windows 95/98 Kernel ModeEnvironment

[1103] Because the embedded timer event handler is invoked in aninterrupt context, it cannot access DM_EVT's self. To accommodate thisrestriction, a structure is allocated that can be shared betweenDM_EVT's operations and the timer event handler utilizing an interruptlevel critical section for synchronization. This structure is allocatedon each arm and is freed either by a disarm call or by the messagehandler in DM_EVT's de-synchronization mechanism (see the followingsection).

[1104] Access to this structure is shared between operations in DM_EVTand the embedded timer event handler, requiring an interrupt levelcritical section to synchronize access to it.

[1105] No specific data structures are used in Windows NT Kernel Modeimplementation.

[1106] 24.3. Mechanisms Used in Windows NT Kernel Mode Environment

Timer Initialization

[1107] At creation time DM_EVT initializes a kernel-mode timer objectand a deferred procedure call structure (KDPC). DM_EVT initializes theKDPC with the timer callback function and first callback parameter apointer to self. The KDPC structure is passed as a parameter when DM_EVTset the timer object.

Generating Timer Events

[1108] DM_EVT passes a time period and the deferred procedure structureto KeSetTimerEx( ). When the time period expires, the deferred procedureis invoked which posts a VM_EVT_TIMER message to DM_EVT tode-synchronize the timer object event.

Arming and Disarming

[1109] DM_EVT is armed and disarmed via the evs operation calls arm anddisarm, respectively. When called on evs.arm, DM_EVT sets the timeperiod with KeSetTimerEx( ) and returns. The timer event set byKeSetTimerEx( ) can be periodic or single event, depend on theparameters passed.

[1110] When called on evs.disarm, DM_EVT disarmd the timer by callingKeCancelTimer( ).

De-synchronization

[1111] The VM_EVT_TIMER message handler checks the context against theone stored in the self (changed after each disarm operation) and, if itmatches, invokes the evs.fire operation, otherwise it returns CMST_OK.

[1112] 24.4. Mechanisms Used in Windows 95/98 Kernel Mode Environment

Generating Timer Events

[1113] DM_EVT passes a time period to and registers a callback procedurewith the VMM service Set_Async_Time_Out( ). When the time periodexpires, the callback procedure is invoked, which posts a message toDM_EVT to de-synchronize the VMM timer event (called during interrupt).The method that receives the posted message invokes the evs.fireoperation synchronously, if DM_EVT's state allows (e.g., the timer wasnot disarmed before message was de-queued).

Arming and Disarming

[1114] DM_EVT is armed and disarmed via the evs operation calls arm anddisarm, respectively. When called on evs.arm, DM_EVT creates a criticalsection and allocates a context for the embedded timer and registers itwith Set_Async_Time_Out( ). DM_EVT also passes Set_Async_Time_Out( ) acallback and a time period. The pointer to the context is saved in theself.

[1115] When called on evs.disarm, DM_EVT checks the embedded timercontext and, if a timer event is pending, calls Cancel_Time_Out( ) andfrees the context. If a timer event is not pending, the critical sectionis destroyed and the pointer to the context in the self is set to NULL.

De-synchronization

[1116] When the callback procedure registered with Set_Async_Time_Out( )is invoked, the state in the received context is checked to determine ifa periodic timer is specified, at which a new event is registered. AVM_EVT_FIRE message is then posted to DM_EVT.

[1117] The VM_EVT_FIRE message handler checks the context pointeragainst the one stored in the self (by the arm operation) and, if itmatches, invokes the evs.fire operation. If there are no pending timerevents, DM_EVT will free the context and move into a disarmed state.

Managing the Context for the Embedded Timer

[1118] The event handler for the embedded system timer executes in aninterrupt context, therefore, it cannot access the self. A context thatcan be shared between DM_EVT's normal operation handlers and the timerevent handler is allocated by the evs.arm operation and freed either bythe evs.disarm operation or, if already referenced by a posted message,by the handler that receives the message. Reference counters aremaintained inside the structure to store the necessary state todetermine when the context should be freed (more than one message withthe same context may be queued). Additionally, a critical section objectis stored in the context and is always accessed before any other fieldis touched. The critical section is used for synchronization of accessto this context.

DM_IRQ—Interrupt Event Source

[1119]FIG. 6 illustrates the boundary of the inventive DM_IRQ part.

[1120] DM_IRQ is an interrupt event source that generates events when ahardware interrupt occurs. DM_IRQ is enabled and disabled via inputoperations on its out terminal and generates interrupt events byinvoking preview and/or submit output operation on the same terminal.

[1121] DM_IRQ may be enabled and disabled only at PASSIVE_LEVEL. Onceenabled, DM_IRQ will invoke preview and submit operations on its outterminal whenever interrupts occur. Disabling the DM_IRQ will stopgeneration of output operations through the out terminal. If theautoenable property is set, enabling of the DM_IRQ is executedinternally at activation time.

[1122] A user-defined context is passed back to DM_IRQ upon successfulreturn from preview call. This context is used for the subsequent submitcall, if the client returns with status CMST_SUBMIT. DM_IRQ maintainstatistics counters for the number of generated interrupts, the numberof submit commands issued through the out terminal and the number of“missed” submits.

[1123] Note: The preview operation is executed at interrupt context. Thecorresponding operation handler must be unguarded. The submit operationis executed at DISPATCH_LEVEL.

[1124] Note DM_IRQ may only be used in the NT Kernel Mode environment.

[1125] 25. Boundary

[1126] 25.1. Terminals

[1127] Terminal “out” with direction “bi-dir” and contract in: I_IRQ(vtable) out: I_IRQ_R (vtable). Note: Used to enable and disable theevent source on the input and to send the interrupt event on the outputwhen the interrupt occurs.

[1128] 25.2. Events and Notifications

[1129] None.

[1130] 25.3. Special Events, Frames, Commands or Verbs

[1131] None.

[1132] 25.4. Properties

[1133] Property “bus” of type “DWORD”. Note: number of the bus on whichthe device is placed (Mandatory)

[1134] Property “bus_type” of type “DWORD”. Note: Type of the bus(BUS_TYPE_xxx): BUS_TYPE_INTERNAL (1) BUS_TYPE_ISA (2) BUS_TYPE_EISA (3)BUS_TYPE_MICRCHANNEL (4) BUS_TYPE_TURBOCHANNEL (5) BUS_TYPE_PCI (6) Thedefault value is BUS_TYPE_PCI

[1135] Property “level” of type “DWORD”. Note: IRQ level (IRQL)(Mandatory)

[1136] Property “vector” of type “DWORD”. Note: IRQ vector (Mandatory)

[1137] Property “irq_mode” of type “DWORD”. Note:IRQ_MODE_LEVEL(0)—level-sensitive interrupt.IRQ_MODE_LATCHED(1)—edge-sensitive The default value is IRQ_MODE_LEVEL.

[1138] Property “shared” of type “DWORD”. Note: Boolean TRUE if theinterrupt can be shared. FALSE—IQR must claim exclusive use of thisinterrupt. The default value is TRUE.

[1139] Property “auto_enable” of type “DWORD”. Note: Boolean. Ifnon-zero, IRQ will automatically enable itself on activation. IRQ willreturn REFUSE on any enable call.

[1140] The default value is FALSE.

[1141] Property “cnt_received” of type “DWORD read-only”. Note: Countthe number of received interrupts since DM_IRQ was enabled.

[1142] Property “cnt_submitted” of type “DWORD read-only”. Note: Countthe number of submitted interrupts since DM_IRQ was enabled.

[1143] Property “cnt_missed” of type “DWORD read-only”. Note: Count thenumber of interrupts for which DM_IRQ was not able to execute submitcall.

[1144] 26. Encapsulated Interactions

[1145] HalGetInterruptVector—returns a mapped system interrupt vector,interrupt level, and processor affinity mask that device drivers mustpass to IoConnectInterrupt.

[1146] IoConnectInterrupt—registers an ISR to be called when theinterrupt occurs.

[1147] IoDisconnectInterrupt—unregisters the Interrupt Service Routine(ISR)

[1148] KeInsertQueueDpc—queues a DPC for execution when the IRQL of aprocessor drops below DISPATCH_LEVEL

[1149] KeRemoveQueueDpc—removes a given DPC object from the system DPCqueue.

[1150] InterlockedCompareExchange—an atomic compare and exchangeoperation.

[1151] 27. Specification

[1152] 28. Responsibilities

[1153] 1. Provide sufficient properties to identify the interruptuniquely

[1154] 2. Allocate and connect interrupt on enable or on activate if theproperty auto_enable is set.

[1155] 3. Implement the actual interrupt handler.

[1156] 4. Process incoming interrupts as follows:

[1157] a. call preview

[1158] b. depending on the returned status, create a DPC and queue it

[1159] c. inform the operating system that this interrupt is recognized

[1160] d. maintain the statistic counters

[1161] 5. On disable, clean up properly. Cancel all outstanding DPCs.

[1162] 6. Maintain a stack with free DPC structures. They are used forscheduling deferred procedure calls from which context is called submitoperations.

[1163] 7. Check the current IRQ level on all incoming enable and disablecalls and refuse the operation if the level is not PASSIVE_LEVEL

[1164] 8. Guarantee that the submit comes out on IRQL equal toDISPATCH_LEVEL

[1165] 9. Guarantee that the preview comes out in interrupt context.

[1166] 10. Guarantee that there will not be any preview or submit callsafter the disable operations returns or after it is deactivated.

[1167] 29. Theory of Operation

[1168] 29.1. State Machine

[1169] None.

[1170] 29.2. Main Data Structures

[1171] A stack of 32 KDPC structures used for issuing the deferredprocedure calls.

[1172] 29.3. Mechanisms

Servicing the Interrupt

[1173] When the interrupt occurs, DM_IRQ generates a preview callthrough its out terminal. If the preview returns status CMST_SUBMIT,DM_IRQ schedules a DPC which sends out a submit call with the returnedfrom preview context.

Enabling and Disabling Interrupts

[1174] DM_IRQ expects client to call enable and disable atPASSIVE_LEVEL. The same applies for activation and deactivation withproperty auto_enable set to TRUE. On enable it allocates an interruptand connects an interrupt handler to it. On disable it disconnectsitself from the interrupt and releases all pending DPCs. There will beno outgoing calls after disabling the interrupts.

Allocating memory for the DM_IRQ instance

[1175] The memory allocated for the DM_IRQ instance is from thenon-paged memory pool.

[1176] 30. Usage Notes

[1177] 1. The preview operation on the part connected to the DM_IRQ mustbe unguarded. The preview operation cannot be guarded because it isexecuted in interrupt context.

[1178] 2. If the clients needs to access any data during preview orsubmit it should be in non-paged memory.

[1179] 3. On preview the client is responsible to synchronize access toany data that is shared between the preview handler and the rest of thecode, using appropriate atomic and interlocked operations. Note that noDriverMagic™ APIs may be called during preview.

[1180] 4. While a preview operation is executed it could be preempted atany time by other preview operation with higher priority or running ondifferent processor.

[1181] 5. If the interrupt being serviced is level-sensitive, thepreview operation handler should cause the device to deassert theinterrupt request—otherwise the preview operation will be invokedimmediately upon return. For devices that support multiple causes ofinterrupts, the preview operation needs to clear at least one cause oneach invocation. Since the connected part is not supposed to know thetype of interrupt (edge-sensitive or level-sensitive), the previewhandler should always remove the cause of the interrupt beforereturning.

[1182] 6. There is no limitation for the implementation of submitoperation on the connected part.

[1183] 7. DM_IRQ could send out a submit operation at any time. It is inthe connected part responsibilities to guard itself from submitreentrancy.

Notifiers DM_NFY—Notifier

[1184]FIG. 7 illustrates the boundary of the inventive DM_NFY part.

[1185] DM_NFY is a connectivity part. It passes all events received onits in terminal to its out terminal watching for particular event(trigger) to come. When such trigger event is received, DM_NFY canoptionally send two notifications that such event has been received:before and/or after passing it through its out terminal.

[1186] The ID of the trigger event as well as the IDs of thenotification events are exposed as properties on the DM_NFY boundary.

[1187] 1. Boundary

[1188] 1.1. Terminals

[1189] Terminal “in” with direction “In” and contract I_DRAIN. Note: Allinput events are received here and forwarded to out terminal. The statusreturned is the one returned by the operation on the out terminal. Ifout terminal is not connected, the operation will returnCMST_NOT_CONNECTED. Unguarded. Can be connected when the part is active.

[1190] Terminal “out” with direction “Out” and contract I_DRAIN. Note:All input events received on in terminal are forwarded through here. Canbe connected when the part is active.

[1191] Terminal “nfy” with direction “Out” and contract I_DRAIN. Note:Notifications that the trigger event is received are sent through here.Can be connected when the part is active.

[1192] 1.2. Events and Notifications

[1193] All events received on in terminal are forwarded to out terminal,raising up to two notifications: one before and after the forwarding.

[1194] The event IDs are exposed as properties and therefore can becontrolled by the outer scope.

[1195] The attributes of the notification events are:CMEVT_A_SELF_CONTAINED, CMEVT_A_SYNC, CMEVT_A_ASYNC.

[1196] The pre and post notifications are always allocated on the stack.

[1197] 1.3. Special Events, Frames, Commands or Verbs

[1198] None.

[1199] 1.4. Properties

[1200] Property “trigger_ev” of type “UINT32”. Note: Trigger event ID.Mandatory. Property “pre_ev” of type “UINT32”. Note: Pre-notificationevent ID. Set to EV_NULL to disable issuing a pre-notification. Default:EV_NULL. Property “post_ev” of type “UINT32”. Note: Post-notificationevent ID. Set to EV_NULL to disable issuing a post-notification.Default: EV_NULL.

[1201] 2. Encapsulated Interactions

[1202] None.

[1203] 3. Specification

[1204] 4. Responsibilities

[1205] 1. Pass all events coming on in to out.

[1206] 2. Watch for trigger event and send pre and/or post notificationto nfy when this event arrives.

[1207] 5. Theory of Operation

[1208] DM_NFY passes all events coming at the in terminal through itsout terminal and watches for a particular event to arrive. When theevent arrives, based on its parameters, DM_NFY issues one or twonotifications: before and/or after the event is passed through.

[1209] DM_NFY propagates the status returned on the out terminaloperation back to the caller of the in terminal operation.

[1210] DM_NFY keeps no state.

DM_NFY2—Advanced Event Notifier

[1211]FIG. 8 illustrates the boundary of the inventive DM_NFY2 part.

[1212] DM_NFY2 is a connectivity part. It passes all events received onits in terminal to its out terminal watching for particular event(trigger) to come. When such trigger event is received, DM_NFY2 can sendone or two notifications that such event has been received: beforeand/or after passing it through its out terminal.

[1213] Unlike the standard notifier (DM_NFY), DM_NFY2 allocates thenotification event buses using cm_evt_alloc and allows custom event bussizes and event attributes.

[1214] 6. Boundary

[1215] 6.1. Terminals

[1216] Terminal “in” with direction “In” and contract I_DRAIN. Note: Allinput events are received here and forwarded to out terminal. The statusreturned is the one returned by the operation on the out terminal. Ifout terminal is not connected, the operation will returnCMST_NOT_CONNECTED. Unguarded. Can be connected when the part is active.

[1217] Terminal “out” with direction “Out” and contract I_DRAIN. Note:All input events received on in terminal are forwarded through here. Canbe connected when the part is active.

[1218] Terminal “nfy” with direction “Out” and contract I_DRAIN. Note:Notifications that the trigger event is received are sent through here.Can be connected when the part is active.

[1219] 6.2. Events and Notifications

[1220] All events received on in terminal are forwarded to out terminal,raising up to two notifications: one before and after the forwarding.

[1221] The event IDs, bus size and attributes are exposed as propertiesand therefore can be controlled by the outer scope.

[1222] The pre and post notification event buses are allocated usingcm_evt_alloc.

[1223] See notes at the end of this data sheet for details on freeingself-owned events and events with asynchronous completion.

[1224] 6.3. Special Events, Frames, Commands or Verbs

[1225] None.

[1226] 6.4. Properties

[1227] Property “trigger_ev” of type “UINT32”. Note: Trigger event ID.Mandatory. Property “pre_ev” of type “UINT32”. Note: Pre-notificationevent ID. Set to EV_NULL to disable issuing a pre-notification. Default:EV_NULL.

[1228] Property “pre_ev_bus_sz” of type “UINT32”. Note: Specifies thesize (in bytes) of the event bus used for the pre-notification event.DM_NFY2 zero-initializes the bus and updates the event headerinformation (event id, bus size and attributes) before sending theevent. Default is sizeof (CMEVENT_HDR).

[1229] Property “pre_ev_attr” of type “UINT32”. Note: Pre-notificationevent attributes. These attributes are set by DM_NFY2 after eventallocation. Default: CMEVT_A_SYNC_ANY |CMEVT_A_SELF_CONTAINED

[1230] Property “post_ev” of type “UINT32”. Note: Post-notificationevent ID. Set to EV_NULL to disable issuing a post-notification.Default: EV_NULL.

[1231] Property “post_ev_bus_sz” of type “UINT-32”. Note: Specifies thesize (in bytes) of the event bus used for the post-notification event.DM_NFY2 zero-initializes the bus and updates the event headerinformation (event id, bus size and attributes) before sending theevent. Default is sizeof (CMEVENT_HDR).

[1232] Property “post_ev_attr” of type “UINT32”. Note: Post-notificationevent attributes. These attributes are set by DM_NFY2 after eventallocation. Default: CMEVT_A_SYNC_ANY |CMEVT_A_SELF_CONTAINED

[1233] 7. Encapsulated Interactions

[1234] None.

[1235] 8. Specification

[1236] 9. Responsibilities

[1237] 3. Pass all events coming on in to out.

[1238] 4. Fail activation if CMEVT_A_ASYNC_CPLT and CMEVT_A_SELF_OWNEDattributes are both set for either the pre or post notification eventattributes.

[1239] 5. Watch for trigger event and send pre and/or post notificationto nfy when this event arrives.

[1240] 10. Theory of Operation

[1241] DM_NFY2 passes all events coming at the in terminal through itsout terminal and watches for a particular event to arrive. When theevent arrives, based on its parameters, DM_NFY2 issues one or twonotifications: before and/or after the event is passed through.

[1242] DM_NFY2 propagates the status returned on the out terminaloperation back to the caller of the in terminal operation.

[1243] DM_NFY2 keeps no state.

[1244] 10.1. State Machine

[1245] None.

[1246] 10.2. Main Data Structures

[1247] None.

[1248] 10.3. Mechanisms

[1249] None.

[1250] 11. Notes

[1251] 1. DM_NFY2's activation will fail if CMEVT_A_ASYNC_CPLT andCMEVT_A_SELF_OWNED attributes are both set for either the pre or postnotification event attributes.

[1252] 2. If a notification event allows asynchronous completion(CMEVT_A_ASYNC_CPLT attribute is set) and the return status of the eventprocessing is CMST_PENDING, DM_NFY2 does not free the notificationevent. It is up to the recipient of this event to free the event bus.DM_NFY2 will only free the event if a status other than CMST_PENDING isreturned.

[1253] 3. If a notification event is self-owned (CMEVT_A_SELF_OWNED),DM_NFY2 will only free the event bus if the return status is not equalto CMST_OK.

DM_NFYS—Notifier on Status

[1254]FIG. 9 illustrates the boundary of the inventive DM_NFYS part.

[1255] DM_NFYS passes all operations received from the in terminalthrough the out terminal. If the return status of the operation (passedthrough out) is equal to a specific status, DM_NFYS generates anotification through the nfy terminal.

[1256] The operation status and the notification event ID are set asproperties on DM_NFYS.

[1257] DM_NFYS always returns the status returned from the outoperation. The return status from nfy is ignored.

[1258] 12. Boundary

[1259] 12.1. Terminals

[1260] Terminal “in” with direction “In” and contract I_POLY. Note:v-table, synchronous, infinite cardinality All operations received onthis terminal are forwarded through out.

[1261] Terminal “out” with direction “Out” and contract I_POLY. Note:v-table, synchronous, cardinality 1 All operations received from the interminal are forwarded out through this terminal.

[1262] Terminal “nfy” with direction “Out” and contract I_DRAIN. Note:v-table, synchronous, cardinality 1 Depending on the return status ofthe operation passed through out, DM_NFYS may generate a notificationthrough this terminal.

[1263] 12.2. Events and Notifications Outgoing Event Bus Notes (ev_id)CMEVENT_(—) This notification is generated HDR by DM_NFYS if the returnstatus of the operation forwarded through out is equal to stat. Theevent is sent with the CMEVENT_HDR bus and CMEVT_A_SYNC_ANY andCMEVT_A_SELF_CONTAINED attributes. The event is allocated on the stack.

[1264] 12.3. Special Events, Frames, Commands or Verbs

[1265] None.

[1266] 12.4. Properties

[1267] Property “stat” of type “UINT32”. Note: Return status thatdetermines if DM_NFYS should generate a notification through its nfyterminal. If the return status of the operation forwarded through out isequal to the value of this property, DM_NFYS generates an ev_idnotification. Default is CMST_OK.

[1268] Property “ev_id” of type “UINT32”. Note: ID of the notificationthat DM_NFYS generates through its nfy terminal. Default is EV_NULL (nonotifcation is generated).

[1269] 13. Internal structure

[1270] DM_NFYS is an assembly that is built entirely out of DriverMagiclibrary parts. It is comprised of a “Distributor for Service” (DSV),which forwards unserviced operations to a specific terminal, a “Poly toDrain Adapter” (P2D) that converts I_POLY operations into events, an“Event Notifier” (NFY), which generates a notification when an specificevent is received, and an “Event Stopper” (DST) which terminates theevent flow from NFY.

[1271] Operations received on in are passed through the out terminal. Ifthe return status of the operation is equal to the stat property, theoperation is forwarded to P2D. P2D converts the operation call into anEV_REQ_POLY_CALL event. This event is passed to NFY which generates anev_id notification and passes it out the nfy terminal. TheEV_REQ_POLY_CALL event is then passed to DST where it is consumed.

[1272] If the return status of the forwarded operation is not equal tostat, the status is returned back to the caller and no further operationis needed.

[1273] 14. Subordinate's Responsibilities

[1274] 14.1. DSV—Distributor for Service

[1275] 1. Forwards incoming operation to out2 if the operation is notserviced by out1.

[1276] 14.2. P2D—Poly to Drain Adapter

[1277] 1. Convert operation calls into operation events(EV_REQ_POLY_CALL).

[1278] 14.3. NFY—Event Notifier

[1279] 1. Generates an event through aux when a specific event isreceived on in. The input event is forwarded through out either beforeor after the genereated event is sent through aux.

[1280] 14.4. DST—Event Stopper

[1281] 1. Terminate the event flow by returning a specified status(e.g., CMST_OK).

[1282] 15. Dominant's Responsibilities

[1283] 15.1. Hard Parameterization of Subordinates Part Property Valuenfy trigger_ev EV_REQ_POLY_CALL dsv hunt_if_match TRUE

[1284] 15.2. Distribution of Properties to the Subordinates PropertyName Type Dist To stat UINT32 group dsv.hunt_stat stat UINT32 groupdst.ret_s ev_id UINT32 redir nfy.pre_ev

DM_NFYB—Bi-directional Notifier

[1285]FIG. 10 illustrates the boundary of the inventive DM_NFYB part.DM_NFYB watches the event flow on its in and out terminals forparticular event(s) (i.e., trigger) to come. All events that arereceived on one terminal are passed to the opposite terminal.

[1286] When the trigger event is received, a notification can be sentout the nfy terminal before and/or after passing the event through theopposite terminal.

[1287] 16. Boundary

[1288] 16.1. Terminals

[1289] Terminal “in” with direction “Bidir” and contract I_DRAIN. Note:All incoming events are forwarded to the out terminal. The statusreturned is the one returned by the operation on the out terminal. Thisterminal is unguarded and can be connected when the part is active.

[1290] Terminal “out” with direction “Bidir” and contract I_DRAIN. Note:All incoming events are forwarded to the in terminal. The statusreturned is the one returned by the operation on the in terminal. Thisterminal is unguarded and can be connected when the part is active.

[1291] Terminal “nfy” with direction “out” and contract I_DRAIN. Note:Notifications that a trigger event has been received on either terminalare sent through here. This terminal can be connected when the part isactive.

[1292] 16.2. Events and Notifications

[1293] All events received on in terminal are forwarded to out terminaland visa versa, raising up to two notifications: one before and afterthe forwarding.

[1294] 16.3. Special Events, Frames, Commands or Verbs

[1295] None.

[1296] 16.4. Properties

[1297] Property “trigger_ev” of type “uint32”. Note: Trigger event IDThis property is mandatory. Property “in_pre_ev” of type “uint32”. Note:Pre-notification event ID in response to receiving trigger_ev on the interminal. Set to EV_NULL to disable issuing a pre-notification. Default:EV_NULL.

[1298] Property “in_post_ev” of type “uint32”. Note: Post-notificationevent ID in response to receiving trigger_ev on the in terminal. Set toEV_NULL to disable issuing a post-notification. Default: EV_NULL.

[1299] Property “out_pre_ev” of type “uint32”. Note: Pre-notificationevent ID in response to receiving trigger_ev on the out terminal. Set toEV_NULL to disable issuing a pre-notification. Default: EV_NULL.

[1300] Property “out_post_ev” of type “uint32”. Note: Post-notificationevent ID in response to receiving trigger_ev on the out terminal. Set toEV_NULL to disable issuing a post-notification. Default: EV_NULL.

[1301] 17. Internal Definition

[1302]FIG. 11 illustrates the internal structure of the inventiveDM_NFYB part.

[1303] DM_NFYB is an assembly that is built entirely out of DriverMagiclibrary parts. It is composed of two Bi-directional Splitters (DM_BSP)and two Event Notifiers (DM_NFY).

[1304] 18. Subordinate's Responsibilities

[1305] 18.1. DM_BSP—Bi-directional Splitter

[1306] The two DM_BSP parts provide the necessary plumbing to connectDM_NFYB's bi-directional inputs to the DM_NFY's uni-directional inputand output.

[1307] 18.2. DM_NFY—Event Notifier

[1308] Each of the DM_NFY parts implements the event notificationfunctionality for a single direction (in→out and out→in). When thetrigger event is received, one or two notifications as specified by thexxx.pre_ev and xxx.post_ev properties are sent out the nfy terminal.

[1309] 19. Dominant's Responsibilities

[1310] 19.1. Hard Parameterization of Subordinates

[1311] None.

[1312] 19.2. Distribution of Properties to Subordinates Property nameType Dist To trigger_ev uint32 group in.trigger_ev, out.trigger_evin_pre_ev uint32 redir in.pre_ev in_post_ev uint32 redir in.post_evout_pre_ev uint32 redir out.pre_ev out_post_ev uint32 redir out.post_ev

Adapters DM_P2D—Poly-to-Drain Adapter

[1313]FIG. 13 illustrates the boundary of the inventive DM_P2D part.

[1314] DM_P2D converts I_POLY v-table interface operations toEV_REQ_POLY_CALL events. DM_P2D translates an operation call to an eventby setting up an event control block, which describes the operationcall. The control block contains all the information necessary toreconstruct the call (contract ID, physical mechanism of the operationcall, the operation ID of the operation that was called and theoperation bus passed with the call). This control block is sent out as asynchronous event.

[1315] DM_P2D also enforces that the correct contract ID andsynchronicity is supplied on an attempt to connect to its in input. Theexpected contract ID and synchronicity are specified through theproperty's expected_cid and expected_sync respectively. This allows theowner of DM_P2D to protect against the connection of a wrong terminal.

[1316] 1. Boundary

[1317] 1.1. Terminals

[1318] Terminal “in” with direction “in” and contract I_POLY. Note:v-table, infinite cardinality, synchronous All operations on thisterminal generate an EV_REQ_POLY_CALL event.

[1319] Terminal “out” with direction “out” and contract I_DRAIN. Note:v-table, cardinality 1, synchronous All EV_REQ_POLY_CALL events arepassed out through this terminal.

[1320] 1.2. Events and Notifications

[1321] There are no incoming events. Outgoing Event Bus NotesEV_REQ_POLY_(—) EV_POLY All incoming operations on CALL in are convertedto an EV_REQ_POLY_CALL event and sent through out.

[1322] 1.3. Special Events, Frames, Commands or Verbs

[1323] None.

[1324] 1.4. Properties

[1325] Property “expected cid” of type “UINT32”. Note: This is thecontract ID of the terminal that is allowed to be connected to in. Whenit is 0, the part does not enforce the contract ID. Default is 0.

[1326] Property “expected_sync” of type “UINT32”. Note: This is thesynchronicity of the terminal that is allowed to be connected to in.Default is CMTRM_S_SYNC.

[1327] 2. Encapsulated Interactions

[1328] None.

[1329] 3. Specification

[1330] 4. Responsibilities

[1331] 4. Enforce that the contract ID and synchronicity of the counterterminal of in is the same as the one specified by the expected_cid andexpected_sync properties respectively.

[1332] 5. Convert all I_POLY operations into EV_REQ_POLY_CALL events andsend them out through the out output terminal.

[1333] 5. Theory of Operation

[1334] 5.1. State Machine

[1335] None.

[1336] 5.2. Main Data Structures

[1337] DM_P2D uses the following event control block for theEV_REQ_POLY_CALL events it generates: EVENTX (EV_POLY, EV_REQ_POLY_CALL,CMEVT_A_AUTO, CMEVT_UNGUARDED) // poly event specific data dword cid ;// contract id uint16 mech ; // physical mechanism uint32 op_id ; //operation id void *busp ; // pointer to operation bus END_EVENTX

[1338] 5.3. Mechanisms

Enforcement of Connection Contracts to In

[1339] When DM_P2D is connected on in, it compares the contract ID andsynchronicity provided on the connection with its expected_cid andexpected_sync properties respectively. If either of the two do notmatch, DM_P2D will refuse the connection.

Conversion of in Operations into EV_REQ_POLY_CALL Events

[1340] When DM_P2D is invoked on one of its in operations, DM_P2Dinitializes an event control block and sends an EV_REQ_POLY_CALL eventthrough the terminal out. The header of the control block contains theevent ID (EV_REQ_POLY_CALL), the size of the control block, andattributes (depends upon successful duplication of the operation buspointer).

[1341] The control block also contains information about the operationcall. This includes the physical mechanism used (always v-table) and thecontract ID (expected_cid). The ID of the operation invoked and thepointer to the operation bus are also provided. The operation bus is notinterpreted by DM_P2D; it is treated as an externally supplied context.After DM_P2D initializes the control block, it sends the event throughthe out terminal.

[1342] The attributes of the events generated by DM_P2D depend upon twovariables. The synchronicity of the counter terminal and whether or notthe operation bus is pool allocated. The operation bus is pool allocatedif it is allocated on the heap using the cm_bus_alloc function or thebus_alloc macro.

[1343] The table below describes the attributes of the EV_REQ_POLY_CALLevent that DM_P2D generates. The first column is the synchronicity ofthe counter terminal of the in terminal. The intersections in the tableare the attributes of the event. All events have the CMEVT_A_CONSTattribute. Terminal Pool allocated Non pool allocated synchronicity busbus Synchronous CMEVT_A_SYNC CMEVT_A_SYNC Asynchronous CMEVT_A_SYNC_(—)Invalid ANY and CMEVT_A_SELF_(—) OWNED Both CMEVT_A_SYNC CMEVT_A_SYNC

[1344] 5.4. Use Cases

Operation Invoked on In

[1345] 1. The counter terminal of in invokes one of its operations. Thecall comes to one of in operation handlers (Op1-Op64).

[1346] 2. DM_P2D generates an EV_REQ_POLY_CALL event. The event containsthe following information:

[1347] a. the event ID (EV_REQ_POLY_CALL)

[1348] b. the contract ID (specified by the property expected_cid)

[1349] c. the physical mechanism (CMTRM_M_VTBL)

[1350] d. the operation ID

[1351] e. the operation bus

[1352] f. event attributes (as described in the above table)

[1353] 3. DM_P2D sends the event through its out output.

DM_D2P—Drain-to-Poly Adapter

[1354]FIG. 14 illustrates the boundary of the inventive DM_D2P part.

[1355] DM_D2P converts incoming EV_REQ_POLY_CALL events into operationcalls through the I_POLY out terminal. DM_D2P translates an incomingEV_REQ_POLY_CALL event to an operation call by examining the event. Theevent fully describes the operation call and contains all theinformation necessary to reconstruct the call (contract ID, physicalmechanism, the operation ID and the operation bus passed with the call).This information is used by DM_D2P to reconstruct the operation callthrough its out output.

[1356] DM_D2P also enforces that the correct contract ID is supplied onan attempt to connect to its out output. The expected contract ID isspecified through a property called expected cid. This allows the ownerof DM_D2P to protect against the connection of a wrong terminal.

[1357] 6. Boundary

[1358] 6.1. Terminals

[1359] Terminal “in” with direction “In” and contract I_DRAIN. Note:v-table, infinite cardinality, synchronous This terminal receives allthe incoming events for DM_D2P.

[1360] Terminal “out” with direction “Out” and contract I_POLY. Note:v-table, cardinality 1, synchronous This terminal is used to invokeoperations as described in the event EV_REQ_POLY_CALL.

[1361] 6.2. Events and Notifications Incoming Event Bus NotesEV_REQ_POLY_CALL EV_POLY All incoming events of this type on in areconverted to I_POLY operation calls on out. Any other events areignored.

[1362] 6.3. Special Events, Frames, Commands or Verbs

[1363] None.

[1364] 6.4. Properties

[1365] Property “expected_cid” of type “UINT32”. Note: This is thecontract ID of the terminal that is allowed to be connected to out. Whenit is 0, the part does not enforce the contract ID. Default is 0.

[1366] 7. Encapsulated Interactions

[1367] None.

[1368] 8. Specification

[1369] 9. Responsibilities

[1370] 1. Enforce that the contract ID of the counter terminal of out isthe same as the one specified by the expected_cid property.

[1371] 2. Convert all incoming EV_REQ_POLY_CALL events into outoperation calls.

[1372] 10. Theory of Operation

[1373] 10.1. State Machine

[1374] None.

[1375] 10.2. Main Data Structures

[1376] DM_D2P interprets the following event control block for theEV_REQ_POLY_CALL events it receives: EVENTX (EV_POLY, EV_REQ_POLY_CALL,CMEVT_A_AUTO, CMEVT_UNGUARDED) // poly event specific data dword cid ;// contract id uint16 mech ; // physical mechanism uint32 op_id ; //operation id void *busp ; // pointer to operation bus

END_EVENTX

[1377] 10.3. Mechanisms

Enforcement of Connection Contracts to Out

[1378] DM_D2P has a property called expected_cid. This property lets itsowner parameterize DM_D2P to specify that terminals with a particularcontract may connect to out. On an attempt to connect to out, thecontract ID of the counter terminal is saved so that only the set ofoperations it specifies can be invoked.

Conversion of EV_REQ_POLY_CALL Events into Out Operation Calls

[1379] When DM_D2P receives an EV_REQ_POLY_CALL event, DM_D2Preconstructs the operation call described by the event. The eventcontains information about the operation. This includes the physicalmechanism used (always v-table in this case), the contract ID, the ID ofthe operation to invoke and the pointer to the operation bus. Theoperation bus is not interpreted by DM_D2P; it is treated as anexternally supplied context.

[1380] Upon receiving an EV_REQ_POLY_CALL event, DM_D2P validates theevent for the proper information. DM_D2P then uses the operation ID asan operation index and invokes it. The operation bus from the event ispassed with the operation call. DM_D2P will consume all events itreceives.

[1381] 10.4. Use Cases

Event Sent Through In Input

[1382] The counter terminal of in sends an event to DM_D2P. The raiseoperation handler of DM_D2P is called and receives a pointer to an eventcontrol block.

[1383] 1. DM_D2P validates the event for proper information:

[1384] a. size>=sizeof (EV_POLY)

[1385] b. event ID=EV_REQ_POLY_CALL

[1386] c. contract ID=value specified by the property expected_cid

[1387] d. mechanism=CMTRM_M_VTBL

[1388] e. operation ID is between 1 and 64

[1389] 2. After validation, DM_D2P uses the operation ID minus one as anoperation index and invokes the operation through out. The operation isinvoked with the operation bus received in the event.

[1390] 3. DM_D2P consumes the event, freeing the event bus if it ismarked as self-owned.

DM_NP2D, DM_ND2P and DM_BP2D—Poly-to-Drain and Drain-to-Poly Adapters

[1391]FIG. 15 illustrates the boundary of the inventive DM_NP2D part.

[1392]FIG. 16 illustrates the boundary of the inventive DM_ND2P part.

[1393]FIG. 17 illustrates the boundary of the inventive DM_BP2D part.

[1394] DM_NP2D, DM_ND2P and DM_BP2D constitute a set of adapters thatconvert a v-table interface into an event (I_DRAIN) interface andvice-versa. The set of events is generated by adding the index of thev-table operation to a base value that is provided as a property.

[1395] The adapters propagate the operation data when converting fromone interface to the other. For this reason, the operation data must beidentical between the two interfaces.

[1396] When converting from a v-table interface to event interface, theadapters have an option by which return data from the outgoing event maybe copied to the original operation bus before returning from the call.

[1397] 11. Boundary

[1398] 11.1. Terminals (DM_NP2D)

[1399] Terminal “in” with direction “In” and contract I_POLY. Note: Alloperations on this terminal are converted into events with event IDs ofev_base plus the v-table index of the operation being invoked.

[1400] Terminal “out” with direction “Out” and contract I_DRAIN. Note:All converted events are passed out this terminal.

[1401] 11.2. Terminals (DM_ND2P)

[1402] Terminal “in” with direction “In” and contract I_DRAIN. Note:This terminal receives all of the incoming events.

[1403] Terminal “out” with direction “Out” and contract I_POLY, Note:This terminal is used to invoke operations. The operation that isinvoked is calculated from the event ID received on in less the value ofthe ev_base property. CMST_NOT_SUPPORTED is returned for unrecognizedoperations.

[1404] 11.3. Terminals (DM_BP2D)

[1405] Terminal “poly” with direction “Bidir” and contract I_POLY. Note:Incoming operations are converted to events and forwarded out the outterminal. Terminal “drain” with direction “Bidir” and contract I_DRAIN.Note: All converted events are passed out this terminal. Events receivedon this terminal are converted to operation calls and invoked out the interminal.

[1406] 11.4. Events and Notifications

[1407] The events that are received and generated contain the followingdata:

[1408] 1. CMEVENT_HDR where the event id is in the range (ev_base+0) . .. (ev_base+63)

[1409] 2. Operation Data

[1410] 11.5. Special Events, Frames, Commands or Verbs

[1411] None.

[1412] 11.6. Properties (DM_NP2D)

[1413] Property “ev_base” of type “uint32”. Note: Event base used togenerate event IDs for outgoing events and extract operation IDs forincoming operations. The default is 0×1000800.

[1414] Property “ev_attr” of type “uint32”. Note: Event attributes to beset for outgoing events. The CMEVT_A_ASYNC_CPLT attribute must not beset. The default is CMEVT_A_SYNC_ANY.

[1415] Property “bus_sz” of type “uint32”. Note: Specifies the size ofthe operation bus received on I_POLY operation calls. The default is 0.

[1416] Property “copy_out” of type “uint32”. Note: (Boolean) When TRUE,the contents of the event bus following the CMEVENT_HDR portion arecopied to the original operation bus before returning. The default isTRUE.

[1417] 11.7. Properties (DM_ND2P)

[1418] Property “n_ops” of type “uint32”. Note: Specifies the maximumnumber of operations that can be invoked out the adapter's I_POLYoutput. This property is mandatory.

[1419] Property “ev_base” of type “uint32”. Note: Event base used togenerate event IDs for outgoing events and extract operation IDs forincoming operations. The default is 0×1000800.

[1420] 11.8. Properties (DM_BP2D)

[1421] Property “n_ops” of type “uint32”. Note: Specifies the maximumnumber of operations that can be invoked out the adapter's I_POLYoutput. This property is mandatory.

[1422] Property “ev_base” of type “uint32”. Note: Event base used togenerate event IDs for outgoing events and extract operation IDs forincoming operations. The default is 0×1000800.

[1423] Property “ev_attr” of type “uint32”. Note: Event attributes to beset for outgoing events. The CMEVT_A_ASYNC_CPLT attribute must not beset. The default is CMEVT_A_SYNC_ANY.

[1424] Property “bus_sz” of type “uint32”. Note: Specifies the size ofthe operation bus received on I_POLY operation calls. The default is 0.

[1425] Property “copy_out” of type “uint32”. Note: (Boolean) When TRUE,the contents of the event bus following the CMEVENT_HDR portion arecopied to the original operation bus before returning. The default isTRUE.

[1426] 12. Encapsulated Interactions

[1427] None.

[1428] 13. Specification

[1429] 14. Responsibilities

[1430] 1. Convert all incoming operation calls to events and forward outthe opposite terminal.

[1431] 2. Convert all incoming events to operation calls out theopposite terminal.

[1432] 15. Theory of Operation

[1433] 15.1. State Machine

[1434] None.

[1435] 15.2. Mechanisms

Conversion of I_POLY Calls to Events

[1436] When either poly-to-drain adapter is invoked on its I_POLY input,it allocates an event bus with a size of CMEVENT_HDR+ the value of thebus_sz property. The event ID is calculated from the value of theev_base property plus the v-table index of the operation being called.The event attributes are set to the value of the ev_attr property.

[1437] The contents of the incoming bus are copied to the event bus andthe event is sent out the I_DRAIN output. If the cpy_out property isTRUE, the contents of the event bus are copied back to the operation busbefore returning.

Conversion of Events to I_POLY Operations

[1438] When the drain-to-poly adapter is invoked on its I_DRAIN input,it invokes the operation on its I_POLY output specified by the value ofthe incoming event ID less the value of the ev_base property. Theadapter passes a pointer to the event bus data following the CMEVENT_HDRportion of the incoming event bus as the operation bus. If the incomingevent bus is CMEVENT_HDR, DM_ND2P passes a NULL operation bus wheninvoking the operation through its I_POLY output.

DM_D2M—I_DIO to Memory Adapter

[1439]FIG. 18 illustrates the boundary of the inventive DM_D2M part.DM_D2M is an adapter that translates I_DIO read and write operationsinvoked on its in terminal into I_BYTEARR read and write operations thatare passed through the out terminal.

[1440] All other I_DIO operations invoked through the in terminal arenot supported (CMST_NOT_SUPPORTED) unless otherwise specified (through aproperty).

[1441] DM_D2M is used for a simple translation of device read and writeoperations into memory byte-array operations. Most of the I_DIOoperation parameters are lost in the translation. If greaterfunctionality is desired, DMD2M should not be used (instead use theI_DIO interface directly).

[1442] 16. Boundary

[1443] 16.1. Terminals

[1444] Terminal “in” with direction “Bidir” and contract in: I_DIO out:I_DIO_C. Note: v-table, cardinality 1, synchronous I_DIO read and writeoperations invoked through this terminal are translated into I_BYTEARRoperations and are passed through the out terminal. All other I_DIOoperations are not supported (CMST_NOT_SUPPORTED) unless otherwisespecified by the support_open_close property. Since all operationscomplete synchronously, the output side of in is not used. This terminalis ungaurded.

[1445] Terminal “out” with direction “Out” and contract I_BYTEARR. Note:v-table, cardinality 1, synchronous All read and write operationsinvoked through in are translated into I_BYTEARR operations and arepassed through this terminal.

[1446] 16.2. Events and notifications

[1447] None.

[1448] 16.3. Special Events, Frames, Commands or Verbs

[1449] None.

[1450] 16.4. Properties

[1451] Property “support_open_close” of type “UINT32”. Note: If TRUEI_DIO.open, I_DIO.close and I_DIO.cleanup are supported (i.e., DMD2Mreturns CMST_SUBMIT on preview and CMST_OK on submit). Default is TRUE.

[1452] 17. Encapsulated interactions

[1453] None.

[1454] 18. Specification

[1455] 19. Responsibilities

[1456] Translate I_DIO.read and I_DIO.write operations invoked throughthe in terminal into I_BYTEARR.read and I_BYTEARR.write operations andpass them through out.

[1457] Fail all other I_DIO operations invoked through the in terminalwith CMST_NOT_SUPPORTED unless otherwise specified by thesupport_open_close property.

[1458] 20. Theory of Operation

[1459] 20.1. Mechanisms

Translation of I_DIO Operations into I_BYTEARR Operations

[1460] DMD2M translates the following operations:

[1461] I_DIO.read→I_BYTEARR.read

[1462] I_DIO.write→I_BYTEARR.write

[1463] All other I_DIO operations are not supported unless otherwisespecified by the support open_close property.

[1464] DM D2M uses the fields of the incoming B_DIO bus to fill in thefields for the B_BYTEARR bus without modification and makes the call.When the I_BYTEARR operation returns, DM_D2M returns the status from theoperation.

DM_DIO2IRP—Device I/O to IRP Adapter

[1465]FIG. 19 illustrates the boundary of the inventive DM D102IRP part.

[1466] DM_DIO2IRP is an adapter that converts incoming EV_DIO_RQ_XXXrequests to EV_REQ_IRP requests suitable for submission to WindowsNT/WDM kernel-mode drivers.

[1467] When submitting a request, DM_DIO2IRP either allocates a new IRPor uses the IRP that is provided with the EV_DIO_RQ_XXX request. Whenallocating a new IRP, DM_DIO2IRP determines the number of stacklocations to provide based on the current values of its properties andinitializes the IRP with the appropriate values provided in theEV_DIO_RQ_XXX request.

[1468] 21. Boundary

[1469] 21.1. Terminals

[1470] Terminal “dio” with direction “Bidir” and contract I_DRAIN. Note:Input for device I/O (EV_DIO_RQ_XXX) requests and output for thecompletion events of those requests that are processed asynchronously.DM_DIO2IRP converts the request into an EV_REQ_IRP request (allocatingand initializing an IRP if one is not provided) and forwards the requestto its irp output.

[1471] Terminal “irp” with direction “Bidir” and contract I_DRAIN. Note:DM_DIO2IRP sends converted Device I/O requests in the form of EV_REC_IRPevents out this terminal. DM_DIO2IRP receives EV_REQ_IRP events on thisterminal when asynchronous IRPs have been completed.

[1472] 21.2. Events and notifications Incoming Event Bus NotesEV_DIO_RQ_OPEN B_EV_DIO This event is received on the dio terminal.DM_DIO2IRP requires this event to contain a valid IRP since most driversrequire this request to be generated by the operating system.EV_DIO_RQ_CLOSE B_EV_DIO This event is received on the dio terminal.DM_DIO2IRP requires this event to contain a valid IRP since most driversrequire this request to be generated by the operating system.EV_DIO_RQ_CLEANUP B_EV_DIO This event is received on the dio terminal.DM_DIO2IRP requires this event to contain a valid IRP since most driversrequire this request to be generated by the operating system.EV_DIO_RQ_READ B_EV_DIO When this event is received on the dio terminal,DM_DIO2IRP generates an IRP with a major function code of IRP_MJ_READ.EV_DIO_RQ_WRITE B_EV_DIO When this event is received on the dioterminal, DM_DIO2IRP generates an IRP with a major function code ofIRP_MJ_WRITE. EV_DIO_RQ_IOCTL B_EV_DIO When this event is received,DM_DIO2IRP generates an IRP with a major function code ofIRP_MJ_DEVICE_(—) CONTROL EV_DIO_RQ_INTERNAL_(—) B_EV_(—DIO) When thisevent is IOCTL received, DM_DIO2IRP generates an IRP with a majorfunction code of IRP_MJ_INTERNAL_(—) DEVICE_CONTROL.

[1473] Outgoing Event Bus Notes EV_REQ_IRP B_EV_IRP DM_DIO2IRP sendsthis event out its irp terminal to submit the generated IRP.

[1474] 21.3. Special Events, Frames, Commands or Verbs

[1475] None.

[1476] 21.4. Properties

[1477] Property “n_stk_loc” of type “UINT32”. Note: Number of stacklocations to reserve in new IRP. This property is optional andactivetime. The default value is 0.

[1478] Property “dev_objp” of type “UINT32”. Note: Pointer to deviceobject to use when allocating new IRPs. This property is used only whenn_stk_loc is zero. This property is optional and activetime. The defaultvalue is 0.

[1479] Property “force_new_irp” of type “UINT32”. Note: Boolean: WhenTRUE, new IRPs are allocated and used regardless if an IRP is providedwith the EV_DI_RQ_XXX event. When FALSE, DM_DIO2IRP allocates and uses anew IRP only if one is not provided with the EV_DI_RQ_XXX event. Thedefault is FALSE.

[1480] 22. Encapsulated Interactions

[1481] DM_DIO2IRP is designed to operate within a Windows NT/WDM kernelmode driver. It uses the following system services when allocating newIRPs:

[1482] IoAllocateIrp( )

[1483] IoGetNextIrpStackLocation( )

[1484] IoFreeIrp( )

[1485] 23. Specification

[1486] 24. Responsibilities

[1487] Convert EV_DIO_RQ_XXX requests received on the dio terminal intoEV_REQ_IRP requests and send out the irp terminal.

[1488] Refuse EV_DIO_RQ_OPEN, EV_DIO_RQ_CLOSE, and EV_DIO_RQ_CLEANUPwhen no IRP is provided.

[1489] Refuse EV_DIO_RQ_XXX request if no IRP provided and the n_stk_locand dev_objp properties are 0.

[1490] Set the async completion attribute of the EV_REQ_IRP requestbased on the completion nature of the EV_DIO_RQ_XXX request.

[1491] Send EV_DIO_RQ_XXX completion event out dio when EV_REQ_IRP eventis received on irp.

[1492] 25. Theory of Operation

[1493]FIG. 20 illustrates an advantageous use of the inventiveDM_DIO2IRP part.

[1494] 25.1. State Machine

[1495] None.

[1496] 25.2. Mechanisms

Allocating IRPs

[1497] If DM_DIO2IRP receives an EV_DIO_RQ_XXX request and there is noIRP provided, DM_DIO2IRP will allocate an IRP for the outgoingEV_REQ_IRP request. If an IRP is provided, DM_DIO2IRP uses that IRP whensubmitting the EV_REQ_IRP request.

[1498] If the force new irp property is TRUE, DM_DIO2IRP allocates a newIRP regardless if an IRP is provided with the EV_DIO_RQ_XXX request.

Determining if IRP is Available

[1499] DM_DIO2IRP checks if the DIO_A_NT_IRP attribute is set in theEV_DIO_RQ_XXX bus to determine if the event contains a valid IRP. If theattribute is set, DM_DIO2IRP interprets the ‘ctx’ field of the event busas a pointer to a valid NT driver IRP associated with the event.

Determining Number of Stack Locations

[1500] DM_DIO2IRP uses one of two methods for determining the number ofstack locations to provide when allocating IRPs:

[1501] If the n_stk_loc property is non-zero, DM_DIO2IRP reserves thenumber of stack locations specified by the property.

[1502] Otherwise, DM_DIO2IRP uses the device object pointer specified inits dev_objp property to obtain the number of stack locations needed.

[1503] If a new IRP is needed and both DM_DIO2IRP's n_stk_loc anddev_objp properties are zero, DM_DIO2IRP fails the EV_DIO_RQ_XXXrequest.

Completing EV_DIO_RQ_XXX requests

[1504] DM_DIO2IRP has no state, so in order to complete asynchronousEV_DIO_RQ_XXX requests, DM_DIO2IRP allocates an extended bus for theoutgoingEV_(—REQ_IRP request. The extended portion of the bus contains the following fields:)

[1505] (1) A signature so that DM_DIO2IRP can determine if the requestwas originated by it,

[1506] (2) The pointer to the EV_DIO_RQ_XXX event bus, and

[1507] (3) A flag specifying if DM_DIO2IRP allocated the IRP so that itmay free it when the event completes.

Completion Status Propagation

[1508] When DM_DIO2IRP services a synchronous device I/O request, itreturns the return status from the EV_REQ_IRP request.

[1509] When DM_DIO2IRP services an asynchronous device I/O request, thecompletion status that it returns comes from the completion status ofthe EV_REQ_IRP event and not from the IRP itself.

[1510] 25.3. Use Cases

Submitting Device I/O Requests

[1511] DM_DIO2IRP along with DM_IRPOUT is useful when a part needs toinitiate and submit a device I/O request to a lower driver, but does notwish to deal with the complexities of allocating, initializing, andcompleting IRP.

DM_A2K—ASCII to Keystroke Converter

[1512]FIG. 21 illustrates the boundary of the inventive DM_A2K part.

[1513] DM_A2K converts data that it receives on its input intokeystrokes that it sends out its output. Each key specified in the datawill result in DM_A2K sending at least two keystrokes out its outterminal (i.e., key down and key up) as if the key were actually pressedon the keyboard. For those keys that require multiple keystrokes (e.g.,a capital letter or control key), DM_A2K first outputs the “down”keystrokes for each key followed by the “up” keystrokes in the reverseorder.

[1514] Before processing any data, DM_A2K sends a request for thecurrent lock state out its out terminal. It uses the response todetermine if SHIFT keystrokes need to be generated when outputtingcapital letters and if NUM LOCK keystrokes need to be generated whenoutputting keys on the numeric keypad.

[1515] By default, DM_A2K does not interpret the data it receives on itsinput in any way. Each character is converted and output as is, meaningthat only those keys that have a direct ASCII representation can beconverted. DM_A2K supports only the first 128 ASCII characters.

[1516] To provide support for those keys that do not have a direct ASCIIrepresentation, DM_A2K defines a simple syntax for describing the keys.The syntax is described later in this document.

[1517] 26. Boundary

[1518] 26.1. Terminals

[1519] Terminal “in” with direction “In” and contract I_RAIN (v-table).Note: Input for data that is to be converted to key strokes as if thedata was typed on the keyboard. Terminal “out” with direction “Out” andcontract I_DRAIN (v-table). Note: Output for keystroke events andrequests for current shift and lock state.

Events and Notifications

[1520] Bus Notes Incoming Event EV_MESSAGE B_EV_MSG This event isreceived on DM_A2K's in terminal. It contains data that is to beconverted to key scan codes. Outgoing Event EV_KBD_EVENT B_EV_KBD DM_A2Ksends this event out its out terminal. It contains a key scan code and aflag indicating whether the key is being pressed or released.EV_KBD_GET_STATE B_EV_KBD DM_A2K sends this event out its out terminalto request the current lock state (i.e., CAPS LOCK, NUM LOCK, and SCROLLLOCK).

Special Events, Frames, Commands or Verbs ASCII Representation Syntax

[1521] The following tables describe the set of keys that is supportedby DM_A2K. The first table provides the string representations for thekeys that cannot be specified by a single ASCII character. The secondtable describes those characters that can be specified by a single ASCIIcharacter. Key Description ASCII Representation Control Break CTL-BRKBackspace key BKS SPACE key SP Tab TAB ENTER key ENTER Left SHIFT keyLSHFT or SHFT Right SHIFT key RSHFT Left CTL key LCTL or CTL Right CTLkey RCTL Left ALT key LALT or ALT Right ALT key RALT PAUSE key PAUSECAPS LOCK key CAPLK ESC key ESC PAGE UP key PUP PAGE DOWN key PDN ENDkey END HOME key HOME LEFT ARROW key LARW UP ARROW key UARW RIGHT ARROWkey RARW DOWN ARROW key DARW PRINT SCREEN key PRSCR INSERT key INSDELETE key DEL Left Windows key (Microsoft LWIN Natural Keyboard) RightWindows key (Microsoft RWIN Natural Keyboard) Application Key (MicrosoftAPP Natural keyboard) Numeric keypad keys N0 . . . N9 MULTIPLY key(numeric keypad) NMUL ADD key (numeric keypad NADD SEPERATOR key(numeric NSEP keypad) SUBTRACT key (numeric keypad) NSUB DECIMAL key(numeric keypad) NDEC DIVIDE key (numeric keypad) NDIV Function keys F1. . . F12 NUM LOCK key NUMLK SCROLL LOCK key SCRLK

ASCII Keys

[1522] Description ASCII Character Number keys 0 . . . 9 Letter keys A .. . Z, a . . . z Punctuation and other characters ′ ˜ ! @ # $ %{circumflex over ( )} & * ( (space is also in this list) ) - _ = + { } |; : ′ ″ , < . > / ? Special characters used by [ ] \ DM_A2K when parsingthe ASCII string.

[1523] The data received with the EV_MESSAGE event contains thefollowing types of fields:

[1524] Literal characters—ASCII characters that are output as is

[1525] Special keys—control and special key strokes that don't haveASCII representations

[1526] The following table gives a brief description of the differentfield types and a short example. Field Type Example Description literalL A literal is fixed data (ASCII character) that is converted directlyto a scan code without further interpretation (except for the currentcaps lock state). escape \x20 An escape mechanism to literal \\ specifyliteral characters that \<lit> \[ are recognized by DM_A2K when parsingthe ASCII string (e.g., [, ], \) or control characters that do not havetext representation. When the <lit> portion of the field is anycharacter except ‘x’, DM_A2K declares the character as a literal. Whenthe first character following the ‘\’ is an ‘x’, DM_A2K interprets thefollowing two characters as the hexadecimal equivalent of a literal.special key [ALT-F] A special key field is an ASCII [<key>] [CTL-ALT-representation of key strokes F] that either have no ASCII code [TAB](e.g., shift, CTL-ALT-DEL) or are commonly used control keys (e.g., tab,escape, enter). The square brackets are required. The <key> portion ofthe field is depicted by one or more key representations separated by‘-’. Keys may be specified in any order; the same key cannot bespecified more than once in the field. A maximum of 4 keys may bespecified within the brackets and no nesting of special keys is allowed.

Properties

[1527] Property “do_special” of type “uint32”. Note: Boolean: When TRUE,DM_A2K recognizes the ASCII representation of the non-ASCII characterscontained in square S brackets. The default value is FALSE.

[1528] Property “do_escape” of type “uint32”. Note: Boolean: When TRUE,DM_A2K recognizes the escape literal field described above. The defaultvalue is FALSE.

Encapsulated Interactions

[1529] DM_A2K relies on the following C-runtime library functions:strtoul and strspn. Implementations of these functions must be providedby the driver (using DM_A2K) in order to properly use DM_A2K. A drivermay fail to compile or load if the proper implementations of thesefunctions are not available.

[1530] 1. Specification

Responsibilities

[1531] 1. Interpret data received on the in terminal based on do_specialand do_escape properties and convert the data into a series ofkeystrokes, as if the keys were typed on the keyboard, and send out theout terminal.

[1532] 2. Interpret the current state of the CAPS LOCK key to determineif SHIFT keystrokes should be generated.

[1533] 3. Interpret the current state of the NUM LOCK key to determineif the NUM LOCK keystrokes need to be generated when outputtingkeystrokes for keys on the numeric keypad.

[1534] 4. Assume that the CAPS, NUM, and SCROLL LOCK indicators are offif the EV_KBD_GET_STATE request fails.

Theory of Operation

[1535]FIG. 22 illustrates an advantageous use of the inventive DM_A2Kpart.

State Machine

[1536] None.

Main Data Structures ascii2scan Table

[1537] DM_A2K uses a static table that contains the followinginformation for each ASCII character

[1538] the key scan code,

[1539] whether a SHIFT, CTL, or ALT keystroke needs to be generated inaddition to the key.

[1540] whether the NUM LOCK needs to be on

[1541] whether the character is an alphabetic character

[1542] The ASCII character itself is the index into this table.

string2scan

[1543] DM_A2K uses an additional table to map the special keyrepresentations to their corresponding scan codes. DM_A2K searches thistable synchronously based on the string representation.

Key Stack and Key Queue

[1544] DM_A2K implements a small queue and a stack that it uses tooutput all keystrokes. Key down events are stored on the key_queue andtheir corresponding key up events are simultaneously pushed onto thekey_stack. This ensures that the key up events are sent in the properorder when more than one keystroke is sent (e.g., to output an ‘A’, send“SHIFT down”, “‘a’ down”, “‘a’ up”, “SHIFT up”)

[1545] The size of the queue and stack are based on the followingcriteria:

[1546] A key sequence specified in square brackets (i.e., special keys)cannot be more than 4 keys,

[1547] Each key can potentially be accompanied by a SHIFT, CTL, or ALTkeystroke or a maximum of 4 keys in a single key sequence.

[1548] Each key has the potential to be preceded by a NUM LOCK onkeystroke and followed by a NUM LOCK off keystroke.

[1549] Each key requires two keystrokes: “key down∞ and “key up”.

[1550] Therefore, the queue has a maximum size of 4*4+4*4 =32 and thestack has a depth of 8, which is the number of potential “key up”keystrokes for the 4 keys (not including the NUM LOCK keystrokes).

Mechanisms Determining If SHIFT keystroke should be sent

[1551] DM_A2K outputs a SHIFT keystroke under the following conditions:

[1552] If the key is a lowercase letter and the CAPS LOCK is not on

[1553] If the key is an uppercase letter and the CAPS LOCK is off

[1554] If the key is not a letter and requires a shift. In thissituation, DM_A2K ignores the state of the CAPS LOCK.

[1555] If the SHIFT key is explicitly specified in a special key field.In this situation, DM_A2K ignores the state of the CAPS LOCK.

Outputting Keystrokes

[1556] When DM_A2K receives an EV_MESSAGE event on its in terminal, itfirst requests the current shift and lock state by sending anEV_KBD_GET_STATE request out its out terminal. If the request fails,DM_A2K assumes that the CAPS, SCROLL, and NUM LOCK LED indicators arenot on.

[1557] DM_A2K then synchronously scans the data. For each literal found,DM_A2K performs the following tasks:

[1558] Uses the character to index into its ascii2scan table andretrieves the scan code

[1559] Puts any required SHIFT or CTL key down event onto DM_A2K's queueand pushes the corresponding key up event onto DM_A2K's key stack.

[1560] Put the “key down” event onto the queue and push thecorresponding “key up” event onto the key stack.

[1561] Pops each “key up” event from the key stack and puts the eventonto the queue.

[1562] Output all keystrokes that are on the queue thereby emptying thequeue.

[1563] If DM_A2K is configured to interpret escape characters (i.e., itsdo escape property is set to TRUE), DM_A2K converts the escaperepresentation into a character and performs the same sequence ofoperations described above.

[1564] If DM_A2K is configured to interpret special keys (i.e., its dospecial property is set to TRUE), DM_A2K searches its string2scan tablefor the string representation and outputs the appropriate keystrokes.The sequence of tasks is the same for a literal except that DM_A2K mayturn the NUM LOCK on or off by sending key down and key up keystrokes asrequired by the key.

[1565] After the keystrokes for the key have been outputted and DM_A2Ktoggled the NUM LOCK, the NUM LOCK state is restored.

Handling Errors and Overflow

[1566] DM_A2K may encounter any of the following errors:

[1567] ASCII character specified in data is above 127 (i.e., size of theascii2scan table)

[1568] Hexadecimal representation specified by “\xhh” is not a validhexadecimal value (i.e., ‘h’ is not a hexadecimal digit)

[1569] Text representation of non-ASCII and control keys is unknown

[1570] DM_A2K encounters a stack or queue overflow.

[1571] When DM_A2K encounters an error, it will discontinue furtherprocessing of the data, discard any keystrokes currently on its queueand stack, and return a bad status.

Use Cases Emulating Keystrokes

[1572] DM_A2K provides an operating system-independent interface bywhich to generate keystrokes from ASCII text. The KBD part connected toDM_A2K's output provides the operating system-dependent mechanism forfeeding keystrokes into the Windows keyboard buffer as if the keys wereactually typed by the user.

DM_IES—Idle to Event Source Adapter

[1573]FIG. 23 illustrates the boundary of the inventive DM_IES part.

[1574] DM_IES is an adapter that makes it possible to connect parts thatrely on idle generation (i.e., DM_DWI) to event sources (i.e., DM_EST).DM_IES converts EV_(—REQ_ENABLE and EV)_(—REQ_DISABLE requests received on its idle terminal into arm and disarm operation calls through its evs terminal. DM_IES returns CMST_NOT_SUPPORTED for all other events received on idle.)

[1575] When the event source connected to evs fires (by invoking thefire operation on evs), DM_IES continuously generates EV_IDLE eventsthrough idle until CMST_NO_ACTION is returned from the idle processingor an EV_REQ_DISABLE request is received. This allows, for example, apart connected to the idle terminal to pump events through a system.

[1576] DM_IES passes NULL buses with the arm and disarm operations.DM_IES expects that the event source connected to the evs terminal hassufficient defaults in order to handle this situation.

[1577] 1. Boundary

[1578] 1.1. Terminals

[1579] Terminal “idle” with direction “Plug” and contract I_DRAIN. Note:v-table, cardinality 1, synchronous, unguarded The requestsEV_REQ_ENABLE and EV_REQ_DISABLE are expected to be received on thisterminal. DM_IES sends EV_IDLE events out this terminal in response tofire operation calls invoked through the evs terminal from an eventsource.

[1580] Terminal “evs” with direction “Bidir” and contract “In: I_EVS_ROut: I_EVS”. Note: v-table, cardinality 1, synchronous, unguarded DM_IESinvokes the arm and disarm operations through this terminal in responseto receiving EV_REQ_ENABLE and EV_REQ_DISABLE requests from the idleterminal respectively. DM_IES sends EV_IDLE events out the idle terminalin response to fire operation calls invoked through this terminal froman event source.

[1581] 1.2. Events and Notifications Incoming Event Bus NotesEV_REQ_ENAB CMEVENT_(—) This request is expected to LE HDR be receivedon the idle terminal. In response to this request, DM_IES invokes thearm operation through the evs terminal. EV_REQ_DISA CMEVENT_ This eventis expected to BLE HDR be received on the idle terminal. In response tothis request, DM_IES invokes the disarm operation through the evsterminal and halts any idle generation from a previous fire.

[1582] 1.3. Outgoing Event Bus Notes EV_IDLE CMEVENT_(—) This event issent through HDR the idle terminal. EV_IDLE is generated by DM_IES whenthe fire operation is invoked through the evs terminal.

[1583] 1.4. Special Events, Frames, Commands or Verbs

[1584] None.

[1585] 5 1.5. Properties

[1586] Property “force_free” of type “UINT32”. Note: Set to TRUE to freeself-owned events received from the idle terminal. Default: FALSE.

[1587] 2. Encapsulated Interactions

[1588] None.

[1589] 3. Specification

[1590] 4. Responsibilities

[1591] 1. In response to receiving EV_REQ_ENABLE and EV_REQ_DISABLErequests on the idle terminal, invoke the arm and disarm operations onthe evs terminal respectively.

[1592] 2. Return CMST_NOT_SUPPORTED for unknown events received on theidle terminal.

[1593] 3. In response to fire operation calls through the evs terminal,generate EV_IDLE requests through idle until CMST_NO_ACTION is returnedfrom the idle processing or an EV_REQ_DISABLE request is received.

[1594] 4.1. State Machine

[1595] None.

[1596] 4.2. Main Data Structures

[1597] None.

[1598] 4.3. Mechanisms

Generating EV_IDLE Events in Response to “fire” Operations

[1599] After anEV_(—REQ_ENABLE request is sent to DM_IES and the event source is armed, DM_IES does nothing until the event source fires at a later time.)

[1600] When the fire operation is invoked through evs, DM_IEScontinuously generates EV_IDLE events through idle until CMST_NO_ACTIONis returned from the idle processing or an EV_REQ_DISABLE request isreceived.

[1601] DM_IES does not support fire previews. See the I_EVS interfacefor more information.

[1602] DM_IES does not rely on any parameters passed with the fireoperation. Note if DM_IES is disabled and then enabled directlyafterwards (while in the context of handling an EV_IDLE event fromDM_IES), DM_IES will continue to generate idle events.

[1603] 4.4. Use Cases

[1604]FIG. 24 illustrates an advantageous use of the inventive DM_IESpart.

Using DM_IES to Create a Thread-based Pump for Event Distribution

[1605] Please refer to the DM_DWI and DM_EST documentation for detailson how they work.

[1606] 1. The structure in FIG. 2 is created, connected, and activated.

[1607] 2. Events, requests and notifications are sent through the interminal of DM_DWI.

[1608] 3. DM_DWI enqueues the events and issues an EV_REQ_ENABLE requestthrough its idle terminal (only for the first event received).

[1609] 4. DM_IES receives the enable request and invokes the armoperation through its evs terminal. DM_IES propagates the return statusof the operation back to DM_DWI. (This use case assumes the armoperation completed successfully). The event source is armed and willfire according to its default settings.

[1610] 5. DM_EST eventually fires by invoking the fire operation throughits evs terminal.

[1611] 6. DM_IES receives the fire operation call and generates EV_IDLEevents through the idle terminal until CMST NO ACTION is returned.

[1612] 7. For each idle event received, DM_DWI dequeues an event andsends it through the out terminal. DM_DWI returns CMST_OK as long asthere are more events to send out on its queue.

[1613] 8. Part A receives the events from DM_DWI and handles themaccordingly.

[1614] 9. Eventually, DM_DWI's queue becomes empty and it sends anEV_REQ_DISABLE request through its idle terminal and returnsCMST_NO_ACTION in response to the last EV_IDLE event.

[1615] 10. DM_IES receives the disable request and disarms the eventsource by invoking the disarm operation through the evs terminal.

[1616] 11. In response to the CMST_NO_ACTION return status, DM_IES stopsgenerating EV_IDLE events, sets the completion status to CMST_OK, andreturns control back to the event source (by returning from the fireoperation call).

[1617] 12. Steps 2-11 may be repeated again once another event is sentto DM_DWI.

DM_PLT—PnP-to-LFC Event Translator

[1618]FIG. 25 illustrates the boundary of the inventive DM_PLT part.DM_PLT translates the Plug-n-Play IRP events(EV_(—REQ_IRP) coming on its in terminal into life-cycle (LFC) events (EV_LFC_xxx) and forwards these through its out terminal.)

[1619] Life-cycle events can be completed asynchronously. DM_PLT willcomplete the IRP event whenever the respective life-cycle eventcompletes. If completion of the life-cycle event is not detected incertain period of time, DM_PLT will automatically complete the IRP eventwith CMST_TIMEOUT.

[1620] To complete the IRP event, DM_PLT will sendEV_(—REQ_IRP event with CMEVT_A_COMPLETED attribute set back to in.)

[1621] 5. Boundary

[1622] 5.1. Terminals

[1623] Terminal “in” with direction “Plug” and contract I_DRAIN. Note:IRP events (EV_REQ_IRP). All events that come at this terminal arecompleted asynchronously. The back channel of this terminal is used forcompletion events only. Can be connected at Active Time.

[1624] Terminal “out” with direction “Plug” and contract I_DRAIN. Note:Life-cycle events. The back channel is used for completion events only.Can be connected at Active Time.

Events and Notifications Passed Through the “in” Terminal

[1625] Incoming Event Bus Notes EV_REQ_IRP B_EV_IR Indicates that IRP Pneeds processing. Outgoing Event Bus Notes EV_REQ_IRP B_EV_IR Indicatesthat IRP P processing has completed. This event is a copy of the eventthat was processed asynchronously with CMEVT_A_COMPLET ED attribute set.

[1626] 1.1. Events and Notifications passed through the “out” terminalOutgoing Event Bus Notes EV_LFC_REQ_START B_EV_L Request to start FCnormal operation. EV_LFC_REQ_STOP B_EV_L Request to stop FC normaloperation. EV_LFC_REQ_DEV_PAU B_EV_L Request to put the SE FC device ina “paused” state. EV_LFC_REQ_DEV_RES B_EV_L Request to revert the UME FCdevice from “paused” state to normal. EV_LFC_NFY_DEV_REM B_EV_LNotification that the OVED FC device has been removed.

[1627] 1.2. Special Events, Frames, Commands or Verbs

[1628] Upon receiving EV_REQ_IRP event on its in terminal, DM_PLTperforms a secondary dispatch by IRPs minor function code for PnP IRPs(IRP_MJ_PNP).

[1629] For details on the expected order of IRP events and the order ofoutgoing LFC events, see the DM_PNS sheet.

[1630] 1.3. Properties

[1631] Property “cplt_tout” of type “UINT32”. Note: LFC completiontimeout in miliseconds. Redirected to subordinate TMR, property time.Default: 3000

[1632] 2. Encapsulated Interactions

[1633] DM_PLT is an assembly and does not utilize such interactions. Itssubordinates, however, may do so, depending on their implementation. Formore information on the subordinates, please refer to the data sheetsof:

[1634] DM_EVT

[1635] DM_PNS

[1636] 3. Internal Definition

[1637]FIG. 26 illustrates the internal structure of the inventive DM_PLTpart.

Theory of Operation

[1638] DM_PLT is an assembly. The main goal of this assembly is toenhance the functionality of the DM_PNS (PnP-to-LFC State Machine) partwith timeout capabilities and provide a simpler boundary.

[1639] The assembly uses a standard part DM_EVT to provide timer eventto DM_PNS and a Event Stopper (DM_STP—standard part) to disable the flowcontrol capabilities of DM_PNS.

Subordinate Parameterization

[1640] Subordinate Property Value tmr time 3000

DM_ERC—Event Recoder

[1641]FIG. 27 illustrates the boundary of the inventive DM_ERC part.

[1642] DM_ERC is used to remap event IDs and attributes in an eventflow. The event IDs and attributes to be remapped are specified asproperties.

[1643] When DM_ERC receives an event on its in terminal, it first checksif the event ID needs to be remapped. If so, the event ID is remappedaccording to the out_base property. Second, DM_ERC checks if the eventattributes need to be remapped. If so, DM_ERC remaps the attributes andthen passes the event through the out terminal.

[1644] 1. Boundary

[1645] 1.1. Terminals

[1646] Terminal “in” with direction “In” and contract I DRAIN. Note:Synchronous, v-table, infinite cardinality, floating The attributes andevent IDs of the incoming events are remapped (if needed) and are passedthrough out. This terminal is unguarded. Terminal “out” with direction“Out” and contract I_DRAIN. Note: Synchronous, v-table, cardinality 1,floating Events received from the in terminal are remapped (if needed)and are passed out this terminal. This terminal is unguarded.

[1647] 1.2. Events and Notifications

[1648] DM_ERC is parameterized with the event IDs of the events passedthrough out. If needed, DM_RC remaps the incoming events and theirattributes and passes them through out.

[1649] 1.3. Special Events, Frames, Commands or Verbs

[1650] None.

[1651] 1.4. Properties

[1652] Property “in base” of type “UINT32”. Note: Base ID for incomingevents. Default is

[1653] 0.

[1654] Property “out base” of type “UINT32”. Note: Base ID for outgoingevents. Default is 0.

[1655] Property “n_events” of type “UINT32”. Note: Number of events toremap, starting from xxx_base. Default is 0.

[1656] Property “attr_mask” of type “UINT32”. Note: Event attribute maskof event attributes to remap. Default is 0.

[1657] Property “attr_val” of type “UINT32”. Note: Event attributevalues of event attributes to remap. Default is 0.

[1658] Property “and_attr” of type “UINT32”. Note: Event attributes thatare ANDed with the incoming event's attributes. Used only if the event'sattributes are to be remapped. Default is 0×FFFFFFFF.

[1659] Property “or_attr” of type “UINT32”. Note: Event attributes thatare ORed with the incoming event's attributes. Used only if the event'sattributes are to be remapped. Default is 0.

[1660] Property “xor_attr” of type “UINT32”. Note: Event attributes thatare XORed with the incoming event's attributes. Used only if the event'sattributes are to be remapped. Default is 0.

[1661] Property “enforce_const” of type “UINT32”. Note: If TRUE, DM_ERCdoes not modify constant events (CMEVT_A_CONST attribute is enforced).Attempts to do so result in an CMST_REFUSE status. If FALSE, DM_ERCmodifies the event without consideration of the constant attribute.Default: TRUE.

[1662] Property “force_free” of type “UINT32”. Note: Set to TRUE to freeself-owned events received from the in terminal. Default: FALSE.

[1663] 2. Encapsulated Interactions

[1664] None.

[1665] 3. Specification

[1666] 4. Responsibilities

[1667] 1. Remap the incoming event ID if needed (as specified byproperties).

[1668] 2. Remap the incoming event attributes if needed (as specified byproperties).

[1669] 3. Refuse to remap any events that have the constant(CMEVT_A_CONST) attribute set only if the enforce_const property isTRUE.

[1670] 5. Theory of Operation

[1671] 5.1. State Machine

[1672] None.

[1673] 5.2. Main Data Structures

[1674] None.

[1675] 5.3. Mechanisms

Remapping Event IDs

[1676] The incoming event IDs to be remapped are specified by settingthe in_base, out_base and n_events properties. The event ID is remappedif it falls in the range of in_base . . . in_base+n_events-1.

[1677] The outgoing event ID is calculated by using the out_base andin_base properties. The formula for calculating the outgoing event IDis: out_base+(incoming event ID−in_base). There is a one-to-onecorrespondence between the incoming event IDs and the outgoing event IDsgenerated by DM_ERC.

Remapping Event Attributes

[1678] The incoming event attributes to be remapped are specified bysetting the attr_mask and attr_val properties. DM_ERC performs abit-wise AND between the event attributes and the value of attr_mask;the result is then compared to attr_val. If there is an exact match, theattributes are remapped according to the and_attr, or_attr and xor_attrproperties.

[1679] If in_base is non-zero, attributes are considered for remappingonly if the ID of the incoming event falls in the range in_base . . .in_base+n_events-1.

[1680] If in_base is zero, the event attributes are always remapped aslong as they meet the criteria described above.

Use Cases Remapping a Single Event ID

[1681] 1. DM_ERC is created and parameterized with the following:

[1682] a. in_base=0'222

[1683] b. out_base=0×333

[1684] c. n_events=1

[1685] 2. DM_ERC is activated.

[1686] 3. An event with the ID of 0×222 is passed to DM_ERC through itsin terminal.

[1687] 4. DM_ERC remaps the event ID to 0×333 and passes it through itsout terminal.

[1688] 5. DM_ERC does not modify the event attributes.

[1689] 6. Steps 3-4 may be repeated several times.

[1690] 7. DM_ERC is deactivated and destroyed.

Remapping a range of event IDs

[1691] 1. DM_ERC is created and parameterized with the following:

[1692] a. in_base=0×222

[1693] b. out_base=0×333

[1694] c. n_events=5

[1695] 2. DM_ERC is activated.

[1696] 3. Events with the IDs of 0×222 . . . 0×226 are passed to DM_ERCthrough its in terminal.

[1697] 4. DM_ERC remaps the event IDs to 0×333 . . . 0×337 and passesthem through its out terminal.

[1698] 5. DM_ERC does not modify the event attributes.

[1699] 6. Steps 3-4 may be repeated several times.

[1700] 7. DM_ERC is deactivated and destroyed.

Modifying Event Attributes

[1701] 1. DM_ERC is created and parameterized with the following:

[1702] a. attr_mask=CMEVT_A_SYNC | CMEVT_A_ASYNC

[1703] b. attr_val=CMEVT_A_SYNC

[1704] c. or_attr=CMEVT_A_ASYNC

[1705] d. and_attr=˜CMEVT_A_SYNC

[1706] 2. DM_ERC is activated.

[1707] 3. An event with the any event ID and attribute CMEVT_A_SYNC ispassed to DM_ERC through its in terminal.

[1708] 4. DM_ERC does not modify the event ID.

[1709] 5. The event attribute matches (event attr & attr_mask ==attr_val) so DM_ERC modifies the attributes by doing the following:

[1710] a. Adds the CMEVT_A_ASYNC attribute (ORing or_attr)

[1711] b. Removes the CMEVT_A_SYNC attribute (ANDing and_attr)

[1712] The effect is converting the discipline for the distribution ofthe event from synchronous to asynchronous.

[1713] 6. DM_ERC passes the event through its out terminal.

[1714] 7. Steps 3-6 may be repeated several times.

[1715] 8. DM_ERC is deactivated and destroyed.

Modifying Event Attributes of a Specific Event

[1716] 1. DM_ERC is created and parameterized with the following:

[1717] a. in_base=0×222

[1718] b. out_base=0×222

[1719] c. n_events=1

[1720] d. attr_mask=CMEVT_A_SYNC | CMEVT_A_ASYNC

[1721] e. attr_val=CMEVT_A_SYNC

[1722] f. or_attr=CMEVT_A_ASYNC

[1723] g. and attr=˜CMEVT_A_SYNC

[1724] 2. DM_ERC is activated.

[1725] 3. An event with an ID of 0×222 and attribute CMEVT_A_SYNC ispassed to DM_ERC through its in terminal.

[1726] 4. DM_ERC does not modify the event ID.

[1727] 5. The event attribute matches (event attr & attr_mask ==attr_val) so DM_ERC modifies the attributes by doing the following:

[1728] a. Adds the CMEVT_A_ASYNC attribute (ORing or_attr)

[1729] b. Removes the CMEVT_A_SYNC attribute (ANDing and_attr)

[1730] The effect is converting the discipline for the distribution ofthe event from synchronous to asynchronous.

[1731] 6. DM_ERC passes the event through its out terminal.

[1732] 7. Steps 3-6 may be repeated several times.

[1733] 8. DM_ERC is deactivated and destroyed.

Remapping both an Event's ID and Attributes

[1734] 1. DM_ERC is created and parameterized with the following:

[1735] a. in_base=0×100

[1736] b. out_base=0×200

[1737] c. n_events=1

[1738] d. attr_mask=CMEVT_A_SYNC

[1739] e. attr val=CMEVT_A_SYNC

[1740] f. or attr=CMEVT_A_ASYNC

[1741] g. and_attr=˜CMEVT_A_SYNC

[1742] 2. DM_ERC is activated.

[1743] 3. An event with the ID of 0×100 and attribute CMEVT_A_SYNC ispassed to DM_ERC through its in terminal.

[1744] 4. DM_ERC remaps the event ID to 0×200.

[1745] 5. The event attribute matches so DM_ERC modifies the attributesby doing the following:

[1746] a. Adds the CMEVT_A_ASYNC attribute (ORing or_attr)

[1747] b. Removes the CMEVT_A_SYNC attribute (ANDing and_attr)

[1748] The effect is converting a synchronous event to an asynchronousevent.

[1749] 6. DM_ERC passes the event through its out terminal.

[1750] 7. Steps 3-6 may be repeated several times.

[1751] 8. DM_ERC is deactivated and destroyed.

DM_STX—Status Recoder

[1752]FIG. 28 illustrates the boundary of the inventive DM_STX part.

[1753] DM_STX is used to recode return statuses in an event channel.

[1754] DM_STX forwards all events received on the in terminal throughthe out terminal. DM_STX propagates all return status codes back to theoriginal caller with the exception of one—this status is recoded usingthe values of the s1 and s2 properties.

[1755] Cascaded DM_STX's can be used to recode more than one returnstatus.

[1756] The events are not interpreted by DM_STX.

[1757] The terminals are unguarded providing maximum flexibility intheir use.

[1758] 1. Boundary

[1759] 1.1. Terminals

[1760] Terminal “in” with direction “in” and contract I_DRAIN. Note:v-table, infinite cardinality, synchronous, unguarded Events receivedfrom this terminal are forwarded through the out terminal. The event isnot interpreted by DM_STX.

[1761] Terminal “out” with direction “Out” and contract I_DRAIN. Note:v-table, cardinality 1, synchronous, unguarded Events received throughthe in terminal are forwarded through this terminal. The event is notinterpreted by DM_STX.

[1762] 1.2. Events and Notifications

[1763] Events received on the in terminal are forwarded through the outterminal.

[1764] 1.3. Special Events, Frames, Commands or Verbs

[1765] None.

[1766] 1.4. Properties

[1767] Property “s1” of type “UINT32”. Note: Mandatory. This is thestatus that DM_STX will recode to s2 if it is returned from the eventprocessing from the out terminal. Property “s2” of type “UINT32”. Note:Mandatory. This is the status that DM_STX returns (to the counterterminal of in) if the return status from the event processing from theout terminal is s1.

[1768] 2. Encapsulated Interactions

[1769] None.

[1770] 3. Specification

[1771] 4. Responsibilities

[1772] 1. Recode the event processing return status s1 (from the outterminal) to s2.

[1773] 2. Forward all events received from the in terminal through theout terminal.

[1774] 4.1. Use Cases

[1775]FIG. 29 illustrates an advantageous use of the inventive DM_STXpart.

[1776]FIG. 30 illustrates an advantageous use of the inventive DM_STXpart.

Using DM_STX to Recode a Return Status

[1777] 1. Part A, Part B and DM_STX are created.

[1778] 2. DM_STX is parameterized with s1=CMST_NO_ACTION and s2=CMST_OK.

[1779] 3. All the parts are activated.

[1780] 4. Part A sends an event through its out terminal.

[1781] 5. DM_STX receives the event on its in terminal and forwards itthrough the out terminal.

[1782] 6. Part B receives the event and returns CMST_NO_ACTION.

[1783] 7. DM_STX receives the CMST_NO_ACTION return status and returnsCMST_OK.

[1784] 8. Part A receives the CMST_OK status from the event processingand continues execution.

[1785] 9. Steps 4-8 are executed again, this time Part B returnsCMST_FAILED. DM_STX propagates the CMST_FAILED status back to Part A.

Using Cascaded Status Recoders

[1786] This use cause demonstrates the usage when there is a need torecode different statuses along the same channel. In this example, 3status recoders are cascaded—one for each of 3 status' that are recodedto a different status if returned from the event processing on Part B.

[1787] 1. The structure in FIG. 5 is created, parameterized, andactivated.

[1788] 2. Part A sends an event to the first status recoder. The recoderpasses it through the out terminal.

[1789] 3. The second recoder receives the event and passes it throughthe out terminal.

[1790] 4. The third recoder receives the event and passes it through theout terminal.

[1791] 5. Part B receives the event and returns CMST_NO_ACTION. Controlis returned to the second recoder.

[1792] 6. The second recoder receives the CMST_NO_ACTION return statusand returns CMST_OK.

[1793] 7. Part A receives the CMST_OK status from the event processingand continues execution.

DM_ACT—Asynchronous Completer

[1794]FIG. 31 illustrates the boundary of the inventive DM_ACT part.

[1795] DM_ACT is an adapter that converts synchronously completed eventson its out terminal into events that complete asynchronously on in.

[1796] Events that complete asynchronously on out are simply passedthrough with no modification.

[1797] 5. Boundary

[1798] 5.1. Terminals

[1799] Terminal “in” with direction “Plug” and contract I_DRAIN. Note:Incoming events are received here.

[1800] Terminal “out” with direction “Plug” and contract I_DRAIN. Note:Outgoing events are sent through here.

[1801] 5.2. Properties

[1802] Property “cplt_s_offs” of type “UINT32”. Note: Offset in bytes ofthe completion status in the event bus. Mandatory.

[1803] Property “enforce_async” of type “UINT32”. Note: Boolean. Set toTRUE to enforce that the incoming events allow asynchronous completion.If TRUE and the incoming event does not allow asynchronous completion,CMST_REFUSE is returned as an event distribution status.

[1804] 6. Encapsulated Interactions

[1805] None.

[1806] 7. Specification

[1807] 8. Responsibilities

[1808] 1. Transform synchronous completion of an outgoing event intoasynchronous completion of the incoming event that generated the former.

[1809] 9. Theory of Operation

[1810] 9.1. Mechanisms

Transformation of Synchronous Completion to Asynchronous one

[1811] Sending a completion event back to the channel that originatedthe event within the input call simulates asynchronous completion.

[1812] This feature is used by DM_ACT to transform synchronouscompletion of events on its out terminal to events completingasynchronously on in.

[1813] DM_ACT passes all incoming events through its out terminal andfor those that return distribution status different than CMST_PENDING(synchronous completion), DM_ACT stores this status at the completionstatus field in the event bus (the same one passed on in) and returnsCMST_PENDING. The storage for the completion status field is computedfrom cplt_s_offs property and the event bus pointer.

[1814] For events that when passed to out, naturally completeasynchronously (by returning CMST_PENDING), DM_ACT does not do anythingand is only a pass-through channel.

DM_SFMT—String Formatter

[1815]FIG. 32 illustrates the boundary of the inventive DM_SFMT part.

[1816] DM_SFMT modifies a string in the incoming bus by adding a prefixand/or suffix to it and passes the operation to out. The input bus maybe restored before DM_SFMT returns from the operation.

[1817] 10. Boundary

[1818] 10.1. Terminals

[1819] Terminal “in” with direction “in” and contract I_POLY. Note:v-table, infinite cardinality. Add prefix and suffix to string in busand forward operation to out.

[1820] Terminal “out” with direction “out” and contract I_POLY. Note:Output for operations containing modified strings.

[1821] 10.2. Events and Notifications

[1822] None.

[1823] 10.3. Special Events, Frames, Commands or Verbs

[1824] None.

[1825] 10.4. Properties

[1826] Property “offset” of type “UINT32”. Note: Offset of string inevent bus. The default value is 0×00.

[1827] Property “by_ref” of type “UINT32”. Note: (boolean) If TRUE, thestring in the bus is by reference. If FALSE, the string is contained inthe bus. The default value is FALSE.

[1828] Property “max_size” of type “UINT32”. Note: Maximum number ofcharacters that may be stored at offset if string is contained in thebus The default value is 0—no maximum.

[1829] Property “prefix” of type “ASCIZ”. Note: Prefix to be added toincoming string. The default value is“ ”.

[1830] Property “suffix” of type “ASCIZ”. Note: Suffix to be added toincoming string. The default value is “ ”.

[1831] Property “undo” of type “UINT32”. Note: (boolean) If TRUE, thechange to the bus will be restored before returning from the operation.The default is FALSE.

[1832] 11. Encapsulated Interactions

[1833] None.

[1834] 12. Specification

[1835] 13. Responsibilities

[1836] 1. Add prefix and suffix to string in bus for operations receivedon in and forward the operation with modified bus to out.

[1837] 2. Restore bus to original contents before returning from call ifundo is TRUE.

[1838] 14. Theory of Operation

[1839] 14.1. State Machine

[1840] None.

[1841] 14.2. Mechanisms

Dereferencing String

[1842] If the by_ref property is FALSE, then the offset in the bus istreated as a byte location representing the first character of thestring. If the by_ref property is TRUE, then the offset is treated as aDWORD value that represents the pointer to the string.

Handing Strings Contained in the Bus

[1843] When DM_SFMT is invoked on an operation, it first calculates thelength of the new string. If the length of the new string is greaterthan the value of the max_size property, DM_SFMT writes debug output tothe debug console and fails the operation. If there is space, DM_SFMTmodifies the string (in place) in the bus by adding the prefix and/orsuffix, and forwards the operation to its out output.

[1844] Upon return DM_SFMT restores the original string(in place) ifundo is set and returns the status from the call to out.

Handing Strings by Reference

[1845] When DM_SFMT is invoked on an operation that contains a string byreference, it saves the pointer to the original string in the bus sothat it may restore it later. DM_SFMT allocates a new buffer, adds theprefix and suffix to the string, stores the pointer in the bus, andforwards the operation to out.

[1846] If DM_SFMT is unable to allocate the necessary memory, it writesdebug output to the debug console and fails the operation.

[1847] Upon return, DM_SFMT frees its allocated string, restores thesaved pointer in the bus, and returns the status from the call to out ifundo is set.

[1848] If the operation returns CMST_PENDING (indicating that theoperation is going to be completed asynchronously), DM_SFMT doesn't freethe allocated string, displays debug output, and returns the samestatus.

Distributors DM_EVB—Event Bus

[1849]FIG. 33 illustrates the boundary of the inventive DM_EVB part.

[1850] The primary function of DM_EVB is to distribute incoming eventsto all parts connected to its terminals. A special discipline ofdistribution is followed: an incoming event is optionally sent forpreview (if do_pview property is TRUE), if that is successful (returnstatus equals status specified by pview_st_ok), the event is distributedamong the recipients. The participants can be connected to two terminalsfor event distribution: dom and evt. The dom terminal accepts only oneconnection, as the intent is this terminal to be connected to adominant. The evt terminal has unlimited cardinality and can be used forconnecting subordinate parts. This terminal can be connected at activetime; that allows it to be connected to dynamically created parts.

[1851] The part connected to the dom terminal is guaranteed to receivethe incoming events either before or after the parts connected to evtterminal. The “before” or “after” decision is based on the value ofdom_first property. The order of distribution among the parts connectedto the evt terminal is not guaranteed.

[1852] DM_EVB optionally desynchronizes all incoming events beforesending them out through the dom and evt terminals. This is controlledby the sync property.

[1853] If no explicit parameterization is used, DM_EVB will skip thepreview; it will desynchronize and distribute all incoming events firstto all the parts connected to the evt terminal and then to the partconnected to the dom terminal.

[1854] 1. Event Bus Notation

[1855] The horizontal line represents the DM_EVB part. The labels on theline represent the names of the DM_EVB terminals. The line emanatingfrom the pview label represents a unidirectional connection. The lineemanating from the dom label represents a bi-directional connectionbetween DM_EVB and the dominant. The remaining lines emanating from theevent bus are bi-directional connections between DM_EVB's evt terminaland other parts.

[1856] The name of the evt terminal may be omitted; any connection toand from the bus, that doesn't have a terminal label next to it, isassumed to be through the evt terminal.

[1857]FIG. 34 illustrates an advantageous use of the inventive DM_EVBpart.

[1858] 2. Boundary

[1859] 2.1. Terminals

[1860] Terminal “evt” with direction “Bi, In or Out” and contractI_DRAIN . Note: v-table, distinguishable connections, infinitecardinality, synchronous, active-time. General-purpose distributionterminal.

[1861] Terminal “dom” with direction “Bi” and contract I_DRAIN . Note:v-table, cardinality 1, floating, synchronous. Terminal for distributingevents to the dominant (assembly).

[1862] Terminal “pview” with direction “Out” and contract I_DRAIN .Note: v-table, cardinality 1, floating, synchronous. Preview output.Events are sent synchronously through this terminal before they aredesynchronized and distributed further. The status returned by sendingthe event through this terminal determines whether a particular eventwill be distributed further or not. If the return status is the onespecified by pview st ok then the event distribution continues;otherwise the event is ignored and not distributed through any of theother terminals.

[1863] Note Although the evt terminal is a bi-directional terminal, itwill accept a connection in any direction: in, out or bi-directional.

[1864] 2.2. Events and Notifications Incoming Event Bus Notes <all>CMEVENT By default all incoming _HDR events are distributed first/CMEvent to all recipients connected to the evt terminal and then to theone connected to the dom terminal. The dom_first property can reversethis behavior. The distribution can be prevented if: 1. the preview isenabled (do_pview property) AND 2. the pview terminal is connected andpreview operation returns value different than the one set to thepview_st_ok property.

[1865] Outgoing Event Bus Notes <all> CMEVENT See above. _HDR /CMEvent

[1866] 2.3. Special Events, Frames, Commands or Verbs

[1867] None.

[1868] 2.4. Properties

[1869] Property “sync” of type “UINT32”. Note: Boolean. When TRUE,DM_EVB distributes all incoming events synchronously in the thread ofthe caller. Default is FALSE.

[1870] Property “dom_first” of type “UINT32”. Note: Boolean. When TRUE,.DM_EVB distributes the incoming events to the dominant (dom terminal)first and then to all remaining recipients (evt terminal). Default isFALSE.

[1871] Property “do_pview” of type “UINT32”. Note: Boolean. When TRUE,DM_EVB first sends the event synchronously through the pview terminaland, if the status returned matches pview_st_ok, it distributes theevent further through dom and evt terminals. Default is FALSE.

[1872] Property “pview_st_ok” of type “UINT32”. Note: Only the low-order16 bits are used. This is the status that indicates whether the previewoperation is successful or not. If the status returned by the outputthrough pview terminal matches the value set in this property, this isan indication of success for the purposes of further event distribution.Default is CMST_OK.

[1873] Property “detect” of type “UINT32”. Note: Boolean. When TRUE,DM_EVB attempts to detect changes in the bus after distributing theevent to each recipient. In general, setting this property to TRUE willslow down the operation of DM_EVB. The intended use of this property isfor debugging purposes. Default is FALSE.

[1874] Property “enforce” of type “UINT32”. Note: Boolean. When TRUE,DM_EVB enforces that each recipient receives the original copy of thebus as it came with the incoming event. In general setting this propertyto TRUE will slow down the operation of DM_EVB. The intended use of thisproperty is for debugging purposes. Default is FALSE.

[1875] 3. Encapsulated Interactions

[1876] None.

[1877] 4. Specification

[1878] 5. Responsibilities

[1879] 1. Distribute all incoming events to all parts connected to domand evt terminals, in the order specified by the property dom_first.

[1880] 2. Send event for “preview” through pview terminal according todo_pview property if the pview output is connected. Stop furtherdistribution if the preview is not successful.

[1881] 3. Desynchronize all incoming events unless otherwise specifiedin sync property.

[1882] 6. Theory of Operation

[1883]FIG. 35 illustrates an advantageous use of the inventive DM_EVBpart.

[1884] 6.1. State Machine

[1885] None.

[1886] 6.2. Main Data Structures

[1887] None.

[1888] 6.3. Mechanisms

Caller Identification

[1889] DM_EVB uses the connection IDs specified when its evt terminal isconnected in order to be able to distinguish between the connections tothis terminal. As a result, CM_EVT can determine through whichconnection a given event came and not send that event back through thesame connection.

Enforcement of Bus Contents

[1890] Detection of bus changes is done by binary comparison of thecontents of the bus after sending it to an individual recipient.Enforcing the contents of the bus is done by overwriting it with thecontents from the original bus before sending it to the next recipient.

[1891] 6.4. Use Cases

Distribution Among Peers

[1892] In case of peer distribution, the dom terminal is unconnected andno events come in from this terminal—all events come from the evtterminal.

[1893] DM_EVB desynchronizes it (unless sync property is TRUE) and sendsit out to all parts connected to the evt terminal except the one thatsent the event in.

Distribution in an Assembly

[1894] In this case there is a part connected to the dom terminal (thedominant) as well as subordinates connected to the evt terminal. Thereare two possibilities: the dominant sending events to the bus orsubordinate sending events to the bus.

[1895] In the first case DM_EVB desynchronizes the event sent by thedominant and distributes this event to all subordinates connected to theevt terminal.

[1896] In the second case DM_EVB depending on the dom_first propertysends the event first to the dominant and then to the subordinates orbackwards. DM_EVB does not distribute the event to the part that sentit.

Dominant Filters Events out During Preview

[1897] In this case all terminals are connected and the do_pviewproperty is set to TRUE. The dom terminal is connected to the dominant,evt to subordinates and pview to another terminal implemented on thedominant as well.

[1898] When an event comes through evt or dom, DM_EVB sends it outimmediately for preview through the pview terminal. The dominantconnected at the other end, receives this event and decides not todistribute it further. For this to happen, the dominant returnsCMST_CANCELLED or other status code that is different from the value ofthe pview_st_ok property. When the DM_EVB receives such a status, itdoes not distribute the event. This way the event is filtered out.

Dominant Replaces the Event During Preview with Another Event

[1899] In this case, again all terminals are connected and the do_pviewproperty is set to TRUE. The dom terminal is connected to the dominant,evt to subordinates and pview to another terminal implemented on thedominant as well.

[1900] When the dominant receives the event for a preview, it returns astatus different than the value of pview_st_ok property. However, beforeit does that, it sends another event back to the bus through theterminal connected to dom terminal on the DM_EVB.

[1901] Note that at this moment the pview input implementation in thedominant is reentered to preview the newly sent event; the dominant mustbe prepared to handle it properly.

[1902] When the replacement event is previewed successfully, theoriginal event is not distributed further as the dominant rejected(absorbed) it, but the replacement event is distributed as usual—DM_EVBfirst desynchronizes it and then sends it to the subordinates. Notealso, that the new event will reach all subordinates connected to thebus, including the one that generated the event that the dominantrecoded.

Distribution of Notifications in a Static Assembly

[1903] In this case all notification terminals of subordinates areconnected to the evt terminal, dom terminal is connected to an interiorterminal on the assembly (i.e., the dominant), and the pview terminal isconnected to a EV_FLT subordinate which implements the filtering ofnotifications.

[1904] The notifications from subordinates are distributed to all othersubordinates before they go out of the assembly. Note that in most caseswhen filtering is used, it is done by the dominant; in this case thepview terminal of the bus is connected to an interior terminal on theassembly.

[1905] If the assembly does not have need to process the notificationsitself, but it needs to be able to send them out—and, possibly, toaccept incoming events and notifications—the DM_EVB dom terminal can beexposed through the assembly boundary as a pass-through terminal.

[1906] Note Exposing the evt terminal of the event bus through theassembly boundary is strongly discouraged, because: (a) the order ofdistribution through this terminal is not guaranteed, and (b) it ispossible to get a duplicate connection ID between the inner and theouter assembly (ClassMagic generates connection IDs for staticconnections to be unique within the scope of the assembly).

DM_DSV—Distributor for Service

[1907]FIG. 36 illustrates the boundary of the inventive DM_DSV part.DM_DSV forwards all operations received on in to out1 and if the callreturns a status that specifies the operation was not serviced, DM_DSVforwards the operation to out2.

[1908] The status that is returned on in is the last status:

[1909] If the operation is not forwarded to out2, then the status fromout1 is returned.

[1910] If the operation is forwarded to out2, the status from out2 isreturned.

[1911] 7. Boundary

[1912] 7.1. Terminals

[1913] Terminal “in” with direction “in” and contract I_POLY. Note:v-table, infinite cardinality, unguarded. Operations received areforwarded to out1 and if the status returned indicates that theoperation was not serviced, then it is forwarded to out2.

[1914] Terminal “out1” with direction “out” and contract I_POLY. Note:Output for forwarded operations.

[1915] Terminal “out2”with direction “out” and contract I_POLY. Note:Output for operations not serviced by out1.

[1916] 7.2. Events and Notifications

[1917] None.

[1918] 7.3. Special Events, Frames, Commands or Verbs

[1919] None.

[1920] 7.4. Properties

[1921] Property “hunt_stat” of type “UINT32”. Note: Return status torecognize on out1. The default is CMST_NOT_SUPPORTED.

[1922] Property “hunt_if_match” of type “UINT32”. Note: (boolean) IfTRUE, DM_DSV hunts for service on out2 if out1 returned exactlyhunt_stat. If FALSE, hunt for service on out2 only if status on out1doesn't match hunt_stat. The default is TRUE.

[1923] 8. Encapsulated Interactions

[1924] None.

[1925] 9. Specification

[1926] 10. Responsibilities

[1927] 1. Forward all operations received on in to out1. Either returnfrom the call or forward the operation to out2 based on the statusreturned and the values of DM_DSV's hunt_stat and hunt_if_matchproperties.

[1928] 11. Theory of Operation

[1929] 11.1. State Machine

[1930] None.

[1931] 11.2. Mechanisms

[1932] None.

[1933] 11.3. Use Cases

[1934]FIG. 37 illustrates an advantageous use of the inventive DM_DSVpart.

Try out2 if Operation not Served by out1

[1935] If the return status from out1 is equal to the value of thehunt_stat property and the hunt_if_match property is TRUE, DM_DSVforwards the operation to out2.

Try out2 if out1 Fails

[1936] If the return status from out1 is not equal to the value of thehunt_stat property and the hunt_if_match property is FALSE, DM_DSVforwards the operation to out2.

Cascading DM_DSV

[1937] DM_DSV may be cascaded to achieve hunting for service among morethan two terminals.

DM_RPL—Event Replicator

[1938]FIG. 38 illustrates the boundary of the inventive DM_RPL part.

[1939] DM_RPL is a connectivity part. DM_RPL passes the events receivedon its in terminal to the out terminal and, in addition, duplicates themand sends the duplicates to its aux terminal.

[1940] The status returned by the operation on the out terminal ispropagated back to the sender of the event.

[1941] Optionally, DM_RPL can be programmed (through property) to sendthe duplicates before it passes the event out.

[1942] The duplicate events are allocated using the ClassMagic eventallocation mechanism and are always self-owned. All other attributes arekept intact.

[1943] 12. Boundary

[1944] 12.1. Terminals

[1945] Terminal “in” with direction “In” and contract I_DRAIN. Note: Allinput events received here are forwarded to out terminal. The statusreturned is the one returned by the operation on the out terminal. Ifout terminal is not connected, the operation returns CMST_NOT_CONNECTED.Unguarded. Can be connected when the part is active.

[1946] Terminal “out” with direction “Out” and contract I_DRAIN. Note:All events received on in terminal are forwarded through here. Can beconnected when the part is active. Terminal “aux” with direction “Out”and contract I_DRAIN. Note: All duplicate events are sent through here.Can be connected when the part is active.

[1947] 12.2. Events and Notifications

[1948] Each event received on in terminal is forwarded to the outterminal and a duplicate event is sent out through the aux terminal.

[1949] 12.3. Special Events, Frames, Commands or Verbs

[1950] None.

[1951] 12.4. Properties

[1952] Property “aux_first” of type “UINT32”. Note: Set to TRUE to sendthe duplicate events (going through aux terminal) first—before theoriginal event is passed through the out terminal. Default: FALSE.

[1953] 13. Encapsulated Interactions

[1954] None.

[1955] 14. Specification

[1956] 15. Responsibilities

[1957] 6. Pass all events coming on in to out.

[1958] 7. Duplicate events coming on in and send the duplicates to aux.

[1959] 16. Theory of Operation

[1960] DM_RPL duplicates the incoming events and sends the duplicatesthrough a separate terminal. The memory for the duplicates is allocatedusing pool allocation (provided by the ClassMagic engine).

[1961] DM_SEQ—Event Sequencer

[1962]FIG. 39 illustrates the boundary of the inventive DM_SEQ part.

[1963] The primary function of DM_SEQ is to distribute incoming eventsreceived on in to the parts connected to the out1 and out2 terminals.

[1964] The incoming event IDs are parameterized on DM_SEQ—DM_SEQsupports up to 16 events. Each event has a corresponding distributiondiscipline and cleanup event ID (also specified through properties).These properties describe how the events are distributed and also uponfailure, the cleanup event that should be sent.

[1965] DM_SEQ supports four distribution disciplines: fwd_ignore,bwd_ignore, fwd_cleanup, bwd_cleanup. Events may be distributed eithersequentially (out1. . . out2) or backwards (out2 . . . out1). The maindifference is whether DM_SEQ ignores the return status from the eventprocessing (fwd_ignore, bwd_ignore) or takes it into account(fwd_cleanup, bwd_cleanup). See the Mechanisms section for moreinformation on the distribution disciplines.

[1966] The events sent through out1 and out2 can be completed eithersynchronously or asynchronously—DM_SEQ takes care of the propersequencing, completion and necessary cleanup.

[1967] Unrecognized events received on in or aux are passed out throughthe opposite terminal without modification. This enables DM_SEQ to beinserted in any event flow and provides greater flexibility.

[1968] 17. Boundary

[1969] 17.1. Terminals

[1970] Terminal “in” with direction “Plug” and contract I_DRAIN. Note:v-table, synchronous, cardinality 1 Incoming events for distribution arereceived here. All recognized events are distributed according to theirdiscipline. All unrecognized events are passed through aux. Unrecognizedevents (received from aux) are sent out this terminal.

[1971] Terminal “out1” with direction “Plug” and contract I_DRAIN. Note:v-table, synchronous, cardinality 1 Event distribution terminal. Thedistribution depends upon the discipline of the event received on in.

[1972] Terminal “out2”with direction “Plug” and contract I_DRAIN. Note:v-table, synchronous, cardinality 1 Event distribution terminal. Thedistribution depends upon the discipline of the event received on in.

[1973] Terminal “aux” with direction “Plug” and contract I_DRAIN. Note:v-table, synchronous, cardinality 1, floating Unrecognized eventsreceived from this terminal are passed out in. Unrecognized eventsreceived from in are passed out this terminal.

[1974] 17.2. Events and Notifications

[1975] DM_SEQ is parameterized with the event IDs of the events itdistributes to out1 and out2. When one of these events are received fromin, DM_SEQ distributes the event according to its discipline. If thedistribution fails and the discipline allows cleanup, DM_SEQ distributesthe cleanup event in the reverse order from where the distributionfailed.

[1976] If the event received on in can be distributed asynchronously,DM_SEQ will send a completion event through in when the eventdistribution has completed.

[1977] If the event sent through out1 or out2 can be completedasynchronously, the completion event bus must be the same (or similar)for all the events DM_SEQ handles.

[1978] All unrecognized events received from either in or aux are passedthrough the opposite terminal without modification.

[1979] 17.3. Special Events, Frames, Commands or Verbs

[1980] None.

[1981] 17.4. Properties

[1982] Property “unsup_ok” of type “BOOL”. Note: If TRUE, a returnstatus of CMST_NOT_SUPPORTED from the event distribution terminals out1or out2 is remapped to CMST_OK. Default is TRUE.

[1983] Property “async_cplt_attr” of type “UINT32”. Note: Value of theattribute that signifies a recognized event received from in can beprocessed asynchronously. The default is: EVT_A_ASYNC_CPLT

[1984] Property “cplt_attr” of type “UINT32”. Note: Value of theattribute that signifies that the processing of the asynchronous eventdistributed to out1 or out2 has been completed. When an eventdistributed through out1 or out2 is processed asynchronously, thecompletion event passed back to DM_SEQ is expected to have thisattribute set. The default is: EVT_A_COMPLETED

[1985] Property “cplt_s_offs” of type “UINT32”. Note: Offset incompletion event bus for the completion status. The size of the storagemust be at least sizeof (cmstat). Default is 0×0C. (first field in eventbus after standard fields id, sz and attr)

[1986] Property “ev[0].ev_id-ev[15].ev_id” of type “UINT32”. Note: EventIDs that DM_SEQ distributes to out1 and out2 when received on the interminal. The default values are EV_NULL.

[1987] Property “ev[0].disc-ev[15].disc” of type “ASCIZ”. Note:Distribution disciplines for ev[0].ev_id-ev[15].ev id, can be one of thefollowing: fwd_ignore bwd_ignore fwd_cleanup bwd_cleanup See theMechanisms section for descriptions of the disciplines. The defaultvalues are fwd ignore.

[1988] Property “ev[0].cleanup_id-ev[15].cleanup id” of type “UINT32”.Note: Event IDs used for cleanup if the event distribution fails. Thecleanup event is not sent if it is EV_NULL. Cleanup events are used onlyif the distribution discipline is fwd_cleanup or bwd_cleanup. Thedefault values are EV_NULL.

[1989] 18. Encapsulated Interactions

[1990] None.

[1991] 19. Specification

[1992] 20. Responsibilities

[1993] 1. or all unrecognized events received from in, pass out auxwithout modification.

[1994] 2. For all unrecognized events received from aux, pass out inwithout modification.

[1995] 3. For all recognized events received from in, distribute them toout1 and out2 according to their corresponding discipline (parameterizedthrough properties—see the Mechanisms section for definitions of thedistribution disciplines).

[1996] 4. Allow both synchronous and asynchronous completion of thedistributed events.

[1997] 5. Fail the event distribution if a recognized synchronous eventreceived on in is processed asynchronously by out1 or out2.

[1998]6. Track events and their sequences, ignoring events that comeout-of-sequence (e.g., completion coming back through a terminal onwhich DM_SEQ did not initiate an operation; or getting a new eventthrough in while event distribution is in progress).

[1999] 7. Do not process any new recognized events while eventdistribution is pending.

[2000] 8. If so configured, remap the status CMST_NOT_SUPPORTED receivedfrom the event distribution to CMST_OK.

[2001] 21. Theory of Operation

[2002] 21.1. State Machine

[2003] None.

[2004] 21.2. Main Data Structures

[2005] None.

[2006] 21.3. Mechanisms

Event Distribution Disciplines

[2007] The following disciplines are used to define how the recognizedevents received on in are distributed to out1 and out2. These arespecified for each event through properties. There is a one-to-onecorrespondence between a recognized event, cleanup event, and the eventdistribution discipline.

[2008] fwd_ignore (broadcast event forward and ignore return status):

[2009] Send event through out1, ignore return status (if CMST_PENDING,return to the caller—processing of asynchronous event is pending).

[2010] Send event through out2, ignore return status (if CMST_PENDING,return to the caller—processing of asynchronous event is pending).

[2011] Complete event distribution with CMST_OK.

[2012] bwd_ignore (broadcast event backwards and ignore return status):

[2013] Send event through out2, ignore return status (if CMST_PENDING,return to the caller—processing of asynchronous event is pending).

[2014] Send event through out1, ignore return status (if CMST_PENDING,return to the caller—processing of asynchronous event is pending).

[2015] Complete event distribution with CMST_OK.

[2016] fwd_cleanup (broadcast event forward and cleanup on failure):

[2017] Send event through out1, save return status

[2018] If status is CMST_PENDING, return to the caller—processing ofasynchronous event is pending. When asynchronous event has completed,extract completion status.

[2019] If return status or completion status is not CMST_OK, completeevent distribution with failed status

[2020] Send event through out2, save return status

[2021] If status is CMST_PENDING, return to the caller—processing ofasynchronous event is pending. When asynchronous event has completed,extract completion status.

[2022] If return status or completion status is not CMST_OK and thecleanup event id is not EV_NULL, send the cleanup event through out1 andignore the return status (if CMST_PENDING, return to thecaller—processing of asynchronous event is pending. Continue to nextstep only when event processing has completed).

[2023] Complete event distribution with the failed status or CMST_OK ifthe event was distributed successfully. bwd_cleanup (broadcast eventbackwards and cleanup on failure):

[2024] Send event through out2, save return status

[2025] If status is CMST_PENDING, return to the caller—processing ofasynchronous event is pending. When asynchronous event has completed,extract completion status.

[2026] If return status or completion status is not CMST_OK, completeevent distribution with failed status

[2027] Send event through out1, save return status

[2028] If status is CMST_PENDING, return to the caller—processing ofasynchronous event is pending. When asynchronous event has completed,extract completion status.

[2029] If return status or completion status is not CMST_OK and thecleanup event id is not EV_NULL, send the cleanup event through out2 andignore the return status (if CMST_PENDING, return to thecaller—processing of asynchronous event is pending. Continue to nextstep only when event processing has completed).

[2030] Complete event distribution with the failed status or CMST_OK ifthe event was distributed successfully.

[2031] Note that depending on the value of the unsup ok property, aCMST_NOT_SUPPORTED return status from out1 or out2 may be mapped toCMST_OK and the event distribution will continue.

Synchronous and Asynchronous Sequencing

[2032] PDM_SEQ uses sequencer tables that define the steps taken foreach distribution discipline defined above. Steps are performed onlyafter the previous step has completed. Each step may be completed eithersynchronously (getting any status other than CMST_PENDING) orasynchronously (getting a CMST_PENDING status). DM_SEQ uses a sequencerto execute each of the steps, including any cleanups. As long as stepscomplete synchronously, DM_SEQ feeds events automatically into thesequencer to advance to the next step; when an event gets desynchronized(returns CMST_PENDING), DM_SEQ uses the respective completion event (thesame event with the cplt_attr attribute set) to resume feeding thesequencer. When the distribution is complete, DM_SEQ sends the sameevent with the cplt_attr attribute set out the in terminal (only if theoriginal event received from in specified asynchronous completion).

Preventing Reentrancy

[2033] When DM_SEQ receives a completion indication from out1 or out2,it posts a message to itself and processes the indicationasynchronously. This prevents recursion into the part that sent thecompletion indication.

Recognizing Out-of-Sequence Events

[2034] DM_SEQ keeps in its state what was the last event or request itsent out and through which terminal it sent it (out1 or out2). When itgets a completion indication, DM_SEQ asserts that the terminal is thesame and the completed operation was the one DM_SEQ requested.

[2035] If they match, DM_SEQ proceeds with the next step in thesequence. Otherwise, it ignores the indication and prints a message tothe debug console.

[2036] DM_SEQ handles out-of-order requests on in: if it receives a newrecognized event on in while it is in the middle of event distribution(at any stage), DM_SEQ fails that new event/request and prints a messageto the debug console.

Generating Cleanup Events

[2037] The cleanup events sent by DM_SEQ are allocated dynamically (noton the stack). The attributes and size of the event depend upon whetherthe original event is allowed to complete asynchronously. The rules areas follows:

[2038] If the original event is only allowed to complete synchronously:

[2039] size=sizeof (CMEVENT_HDR) attributes=CMEVT_A_SELF_CONTAINED |CMEVT_A_SYNC

[2040] If the original event is allowed to complete asynchronously:

[2041] size=cplt_s_offs+sizeof (cmstat)

[2042] attributes=CMEVT_A_SELF_CONTAINED | CMEVT_A_SYNC async_cplt_attr

[2043] 22. Notes

[2044] 1. DM_SEQ does not allow self-owned events (CMEVT_A_SELF_OWNED)to be distributed through its terminals. Upon receiving such an event,DM_SEQ fails with CMST_REFUSE.

DM_SEQT—Event Sequencer on Thread

[2045]FIG. 40 illustrates the boundary of the inventive DM_SEQT part.

[2046] The primary function of DM_SEQT is to distribute incoming eventsreceived on in to the parts connected to the out1 and out2 terminals.The events sent through out1 and out2 are in the context of DM_SEQT'sworker thread (unlike DM_SEQ where the events are in the context of theDriverMagic's pump thread). Each instance of DM_SEQT preferably has itsown worker thread.

[2047] The incoming event IDs are parameterized on DM_SEQT—DM_SEQTsupports up to 16 events. Each event has a corresponding distributiondiscipline and cleanup event ID (also specified through properties).These properties describe how the events are distributed and also uponfailure, the cleanup event that should be sent.

[2048] DM_SEQT supports four distribution disciplines: fwd ignore, bwdignore, fwd cleanup, bwd cleanup. Events may be distributed eithersequentially (out1 . . . out2) or backwards (out2 . . . out1). The maindifference is whether DM_SEQT ignores the return status from the eventprocessing (fwd_ignore, bwd_ignore) or takes it into account(fwd_cleanup, bwd_cleanup). See the Mechanisms section for moreinformation on the distribution disciplines.

[2049] The events sent through out1 and out2 can be completed eithersynchronously or asynchronously—DM_SEQT takes care of the propersequencing, completion and necessary cleanup.

[2050] Unrecognized events received on in or aux are passed out throughthe opposite terminal without modification. This enables DM_SEQT to beinserted in any event flow and provides greater flexibility.

[2051] 23. Boundary

[2052] 23.1. Terminals

[2053] Terminal “in” with direction “Plug” and contract I_DRAIN. Note:v-table, synchronous, cardinality 1 Incoming events for distribution arereceived here. All recognized events are distributed according to theirdiscipline.

[2054] Terminal “out1” with direction “Plug” and contract I_DRAIN. Note:v-table, synchronous, cardinality 1 Event distribution terminal. Thedistribution depends upon the discipline of the event received on in.

[2055] Terminal “out2”with direction “Plug” and contract I_DRAIN. Note:v-table, synchronous, cardinality 1 Event distribution terminal. Thedistribution depends upon the discipline of the event received on in.

[2056] 23.2. Events and Notifications

[2057] DM_SEQT is parameterized with the event IDs of the events itdistributes to out1 and out2. When one of these events are received fromin, DM_SEQT distributes the event according to its discipline. If thedistribution fails and the discipline allows cleanup, DM_SEQTdistributes the cleanup event in the reverse order from where thedistribution failed.

[2058] If the event received on in can be distributed asynchronously,DM_SEQT will send a completion event through in when the eventdistribution has completed.

[2059] 23.3. Special Events, Frames, Commands or Verbs

[2060] None.

[2061] 23.4. Properties

[2062] Property “thread_priority” of type “UINT32”. Note: Specifies thepriority of the worker thread. The values for this property depend onthe environment. It is used directly to call the environment specificfunction that sets the thread priority (SetThreadPriority in Win32,KeSetPriorityThread in WDM, etc.). This property is redirected to theRDWT subordinates.

[2063] Property “disable_diag” of type “UINT32”. Note: Boolean. Thisdetermines whether DM_RDWT prints debug output indicating that a callthrough out failed. A call through out fails if the return status is notequal to ok_stat. This property affects only the checked build ofDM_RDWT. This property is redirected to the RDWT subordinates. Defaultis FALSE.

[2064] Property “cplt_s_offs” of type “UINT32”. Note: Offset in bytes ofthe completion status in the request bus. This property is redirected tothe RDWT and SEQ subordinates. Mandatory.

[2065]

[2066] Property “ev[0].ev_id-ev[l 51.ev_id” of type “UINT32”. Note:Event IDs that DM_SEQT distributes to out1 and out2 when received on thein terminal. This property is redirected to the SEQ subordinate. Thedefault values are EV_NULL.

[2067] Property “ev[0].disc-ev[15].disc” of type “ASCIZ”. Note:Distribution disciplines for ev[O].ev_id-ev[15].ev_id, can be one of thefollowing: fwd ignore bwd ignore fwd_cleanup bwd_cleanup See theMechanisms section of the DM_SEQ documentation for descriptions of thedisciplines. This property is redirected to the SEQ subordinate. Thedefault values are fwd_ignore.

[2068] Property “ev[O].cleanup_id-ev(15].cleanup_id” of type “UINT32”.Note: Event IDs used for cleanup if the event distribution fails. Thecleanup event is not sent if it is EV_NULL. Cleanup events are used onlyif the distribution discipline is fwd_cleanup or bwd_cleanup. Thisproperty is redirected to the SEQ subordinate. The default values areEV_NULL.

[2069] 24. Encapsulated Interactions

[2070] None.

[2071] 25. Specification

[2072] 26. Responsibilities

[2073] 1. For all recognized events received from in, distribute them toout1 and out2 according to their corresponding discipline (parameterizedthrough properties).

[2074] 2. Allow both synchronous and asynchronous completion of thedistributed events.

[2075] 3. Fail the event distribution if a recognized synchronous eventreceived on in is processed asynchronously by out1 or out2.

[2076] 4. Track events and their sequences, ignoring events that comeout-of-sequence (e.g., completion coming back through a terminal onwhich DM_SEQT did not initiate an operation; or getting a new eventthrough in while event distribution is in progress).

[2077] 5. Do not process any new recognized events while eventdistribution is pending.

[2078] 6. If so configured, remap the status CMST_NOT_SUPPORTED receivedfrom the event distribution to CMST_OK.

[2079] 7. Distribute all events passed out of out1 and out2 in thecontext of DM_SEQT's own worker thread.

[2080] 27. Internal Definition

[2081]FIG. 41 illustrates the internal structure of the inventiveDM_SEQT part.

[2082] 28. Theory of Operation

[2083] DM_SEQT is an assembly built entirely of DriverMagic parts.

[2084] The events received through the in terminal are distributed toout1 and out2 according to their discipline. All events passed out ofout1 and out2 are in the context of DM_SEQT's own worker threads, onefor each channel.

[2085] Please see the DM_SEQ data sheet for more information about thesequencer and how it works.

[2086] 28.1. Mechanisms

Event Distribution Disciplines

[2087] The following disciplines are used to define how the recognizedevents received on in are distributed to out1 and out2. These arespecified for each event through properties. There is a one-to-onecorrespondence between a recognized event, cleanup event, and the eventdistribution discipline.

[2088] fwd_ignore (broadcast event forward and ignore return status):

[2089] Send event through out1, ignore return status (if CMST_PENDING,return to the caller—processing of asynchronous event is pending).

[2090] Send event through out2, ignore return status (if CMST_PENDING,return to the caller—processing of asynchronous event is pending).

[2091] Complete event distribution with CMST_OK.

[2092] bwd_ignore (broadcast event backwards and ignore return status):

[2093] Send event through out2, ignore return status (if CMST_PENDING,return to the caller—processing of asynchronous event is pending).

[2094] Send event through out1, ignore return status (if CMST_PENDING,return to the caller—processing of asynchronous event is pending).

[2095] Complete event distribution with CMST_OK.

[2096] fwd_cleanup (broadcast event forward and cleanup on failure):

[2097] Send event through out1, save return status

[2098] If status is CMST_PENDING, return to the caller—processing ofasynchronous event is pending. When asynchronous event has completed,extract completion status.

[2099] If return status or completion status is not CMST_OK, completeevent distribution with failed status

[2100] Send event through out2, save return status

[2101] If status is CMST_PENDING, return to the caller—processing ofasynchronous event is pending. When asynchronous event has completed,extract completion status.

[2102] If return status or completion status is not CMST_OK and thecleanup event id is not EV_NULL, send the cleanup event through out1 andignore the return status (if CMST_PENDING, return to thecaller—processing of asynchronous event is pending. Continue to nextstep only when event processing has completed).

[2103] Complete event distribution with the failed status or CMST_OK ifthe event was distributed successfully.

[2104] bwd_cleanup (broadcast event backwards and cleanup on failure):

[2105] Send event through out2, save return status

[2106] If status is CMST_PENDING, return to the caller—processing ofasynchronous event is pending. When asynchronous event has completed,extract completion status.

[2107] If return status or completion status is not CMST_OK, completeevent distribution with failed status

[2108] Send event through out1, save return status

[2109] If status is CMST_PENDING, return to the caller—processing ofasynchronous event is pending. When asynchronous event has completed,extract completion status.

[2110] If return status or completion status is not CMST_OK and thecleanup event id is not EV_NULL, send the cleanup event through out2 andignore the return status (if CMST_PENDING, return to thecaller—processing of asynchronous event is pending. Continue to nextstep only when event processing has completed).

[2111] Complete event distribution with the failed status or CMST_OK ifthe event was distributed successfully.

[2112] Note that depending on the value of the unsup_ok property, aCMST_NOT_SUPPORTED return status from out1 or out2 may be mapped toCMST_OK and the event distribution will continue.

Synchronous and Asynchronous Sequencing

[2113] DM_SEQT uses sequencer tables that define the steps taken foreach distribution discipline defined above. Steps are performed onlyafter the previous step has completed. Each step may be completed eithersynchronously (getting any status other than CMST_PENDING) orasynchronously (getting a CMST_PENDING status).

[2114] DM_SEQT uses a sequencer to execute each of the steps, includingany cleanups. As long as steps complete synchronously, DM_SEQT feedsevents automatically into the sequencer to advance to the next step;when an event gets desynchronized (returns CMST_PENDING), DM_SEQT usesthe respective completion event (the same event with the cplt_attrattribute set) to resume feeding the sequencer. When the distribution iscomplete, DM_SEQT sends the same event with the cplt_attr attribute setout the in terminal (only if the original event received from inspecified asynchronous completion).

Preventing Reentrancy

[2115] When DM_SEQT receives a completion indication from out1 or out2,it posts a message to itself and processes the indicationasynchronously. This prevents recursion into the part that sent thecompletion indication.

Recognizing Out-of-Sequence Events

[2116] DM_SEQT keeps in its state what was the last event or request itsent out and through which terminal it sent it (out1 or out2). When itgets a completion indication, DM_SEQT asserts that the terminal is thesame and the completed operation was the one DM_SEQT requested.

[2117] If they match, DM_SEQT proceeds with the next step in thesequence. Otherwise, it ignores the indication and prints a message tothe debug console. DM_SEQT handles out-of-order requests on in: if itreceives a new recognized event on in while it is in the middle of eventdistribution (at any stage), DM_SEQT fails that new event/request andprints a message to the debug console.

Generating Cleanup Events

[2118] The cleanup events sent by DM_SECT are allocated dynamically (noton the stack). The attributes and size of the event depend upon whetherthe original event is allowed to complete asynchronously. The rules areas follows:

[2119] If the original event is only allowed to complete synchronously:

[2120] size=sizeof (CMEVENT_HDR) attributes=CMEVT_A_SELF_CONTAINED |CMEVT_A_SYNC

[2121] If the original event is allowed to complete asynchronously:

[2122] size=cplt_s_offs+sizeof (cmstat)

[2123] attributes=CMEVT_A_SELF_CONTAINED | CMEVT_A_SYNC async_cplt_attr

[2124] 29. Subordinate's Responsibilities

[2125] 29.1. DM_SEQ—Event Sequencer

[2126] For all recognized events received from in, distribute them toout1 and out2 according to their corresponding discipline

[2127] Track events and their sequences, ignoring events that comeout-of-sequence (e.g., completion coming back through a terminal onwhich DM_SEQ did not initiate an operation; or getting a new eventthrough in while event distribution is in progress).

[2128] 29.2. DM_RDWT—Request Desynchronizer with Thread

[2129] Desynchronize all incoming requests received from in and sendthem through out. Use a dedicated worker thread to call the outterminal.

[2130] 30. Dominant's Responsibilities

[2131] 30.1. Hard Parameterization of Subordinates Subordinate PropertyValue SEQ cplt_attr CMEVT_A_COMPLETED async_cplt_attr CMEVT_A_ASYNC_CPLT

[2132] 30.2. Distribution of Properties to the Subordinates PropertyName Type Dist To unsup_ok UINT3 Redir seq.unsup_ok 2 ev[0].ev_id- UINT3Redir seq.ev[0].ev_id- ev[15].ev_id 2 seq.ev[15].ev_id ev[0].disc- UINT3Redir seq.ev[0].disc- ev[15].disc 2 seq.ev[15].disc ev[0].cleanup_id-UINT3 Redir seq.ev[0].cleanup_id- ev[15].cleanup_id 2seq.ev[15].cleanup⁻id

[2133] 31. Notes

[2134] 1. DM_SEQT does not allow self-owned events (CMEVT_A_SELF_OWNED)to be distributed through its terminals. Upon receiving such an event,DM_SEQT fails with CMST_REFUSE.

DM_LFS—Life-Cycle Sequencer

[2135]FIG. 42 illustrates the boundary of the inventive DM_LFS part.

[2136] The primary function of DM_LFS is to distribute incominglife-cycle events received on in to the parts connected to the out1 andout2 terminals.

[2137] DM_LFS relies on DM_SEQ for the event distribution functionality.DM_LFS parameterizes DM_SEQ with life-cycle events (defined below). Seethe hard parameterization section below for a list of life-cycle eventsthat DM_LFS handles. Additional events may be distributed by settingproperties on DM_LFS. For more information about the event distribution,see the DM_SEQ documentation.

[2138] 32. Boundary

[2139] 32.1. Redirected Terminals

[2140] All the following terminals are redirected to DM_SEQ: Terminal“in” with direction “Plug” and contract I_DRAIN. Note: v-table,synchronous, cardinality 1 Incoming events for distribution are receivedhere. All recognized events are distributed according to theirdiscipline. All unrecognized events are passed through aux. Unrecognizedevents (received from aux) are sent out this terminal.

[2141] Terminal “out1“with direction “Plug” and contract I_DRAIN. Note:v-table, synchronous, cardinality 1 Event distribution terminal. Thedistribution depends upon the discipline of the event received on in.

[2142] Terminal “out2”with direction “Plug” and contract I_DRAIN. Note:v-table, synchronous, cardinality 1 Event distribution terminal. Thedistribution depends upon the discipline of the event received on in.

[2143] Terminal “aux” with direction “Plug” and contract I_DRAIN. Note:v-table, synchronous, cardinality 1, floating Unrecognized eventsreceived from this terminal are passed out in. Unrecognized eventsreceived from in are passed out this terminal.

[2144] 32.2. Events and Notifications

[2145] DM_LFS parameterizes DM_SEQ to handle life-cycle events. Theremaining events that can be handled by DM_SEQ can be parameterized fromthe outside of DM_LFS. These are redirected properties on DM_LFS; seebelow for more details.

[2146] 32.3. Special Events, Frames, Commands or Verbs

[2147] None.

[2148] 32.4. Redirected Properties

[2149] All the following properties are redirected to DM_SEQ:

[2150] Property “unsup_ok” of type “BOOL”. Note: If TRUE, a returnstatus of CMST_NOT_SUPPORTED from the event distribution terminals out1or out2 is remapped to CMST_OK. Default is TRUE.

[2151] Property “ev[0].ev_id-ev[11].ev_id” of type “UINT32”. Note: EventIDs that DM_LFS distributes to out1 and out2 when received on the interminal. The default values are EV_NULL.

[2152] Property “ev[0].disc-ev[11].disc” of type “ASCIZ”. Note:Distribution disciplines for ev[0].ev_id-ev[8].ev_id, can be one of thefollowing: fwd_ignore bwd_ignore fwd_cleanup bwd_cleanup See the DM_SEQdocumentation for descriptions of the disciplines. The default valuesare fwd_ignore.

[2153] Property “ev[0].cleanup_-id-ev[11].cleanup_id” of type “UINT32”.Note: Event IDs used for cleanup if the event distribution fails. Thecleanup event is not sent if it is EV_NULL. Cleanup events are used onlyif the distribution discipline is fwd_cleanup or bwd_cleanup. Thedefault values are EV_NULL.

[2154] 32.5. Hard Parameterization

[2155] All the following properties are set on DM_SEQ:

[2156] Property “unsup_ok” of type “BOOL”. Note: TRUE

[2157] Property “async_cplt_attr” of type “UINT32”. Note:EVT_A_ASYNC_CPLT

[2158] Property “cplt_attr” of type “UINT32”. Note: EVT_A_COMPLETED

[2159] Property “cplt_s_offs” of type “UINT32”. Note: 0×0C

[2160] Property “ev[0].ev_id” of type “UINT32”. Note: EV_LFC_REQ_START

[2161] Property “ev[0].disc” of type “ASCIZ”. Note: “fwd_cleanup”

[2162] Property “ev[0].cleanup_id” of type “UINT32”. Note:EV_LFC_REQ_STOP

[2163] Property “ev[1].ev_id” of type “UINT32”. Note: EV_LFC_REQ_STOP

[2164] Property “ev[1].disc” of type “ASCIZ”. Note: “bwd_ignore”

[2165] Property “ev[1].cleanup_id” of type “UINT32”. Note: EV_NULL

[2166] Property “ev[2].ev_id” of type “UINT32”. Note:EV_LFC_REQ_DEV_PAUSE

[2167] Property “ev[2].disc” of type “ASCIZ”. Note: fwd_cleanup”

[2168] Property “ev[2].cleanup_id” of type “UINT32”. Note:EV_LFC_REQ_DEV_RESUME

[2169] Property “ev[3].ev_id” of type “UINT32”. Note:EV_LFC_REQ_DEV_RESUME

[2170] Property “ev[3].disc” of type “ASCIZ”. Note: “fwd_cleanup”

[2171] Property “ev[3].cleanup_id” of type “UINT32”. Note:EV_LFC_REQ_DEV_PAUSE

[2172] 33. Encapsulated Interactions

[2173] None.

DM_MUX—Event-Controlled Multiplexer

[2174]FIG. 43 illustrates the boundary of the inventive DM_MUX part.

[2175] DM_MUX forwards operations received on its in input to either itsout1 or out2 outputs. The outgoing terminal, which DM_MUX forwardsincoming operations to, is controlled via three events it receives onits ctl terminal.

[2176] DM_MUX is parameterized with the three events via properties. Oneevent switches outgoing operations to out1, one event switches outgoingoperations to out2, and the last event toggles the outgoing operationterminal (i.e., out1 if out2 is selected and out2 if out1 is selected)

[2177] By default, DM_MUX forwards operations received its in terminalto its out1 terminal.

[2178] 34. Boundary

[2179] 34.1. Terminals

[2180] Terminal “in” with direction “in” and contract I_POLY. Note:v-table, infinite cardinality, unguarded. Operations received areforwarded to either out1 or out2.

[2181] Terminal “out1” with direction “out” and contract I_POLY. Note:Output for forwarded operations.

[2182] Terminal “out2”with direction “out” and contract I_POLY. Note:Output for forwarded operations.

[2183] Terminal “ctl” with direction “in” and contract I_DRAIN. Note:v-table, infinite cardinality, unguarded. Receive events that controlmultiplexer switching.

[2184] 34.2. Events and Notifications

[2185] DM_MUX recognizes three specific events: ev_out1, ev_out2 andev_toggle on its ctl terminal. The event IDs for these events arespecified as properties and are described in the table below. IncomingEvent Bus Notes (ev_out1) CMEVENT Select out1 for outgoing _HDRoperations. The default is EV_REQ_ENABLE. (ev_out2) CMEVENT Select out2for outgoing _HDR operations. The default is EV_REQ_DISABLE. (ev_toggle)CMEVENT Select the other output for _HDR outgoing operations (i.e., out1if out2 is selected and out2 if out1 is selected). The default isEV_NULL.

[2186] 34.3. Special Events, Frames, Commands or Verbs

[2187] None.

[2188] 34.4. Properties

[2189] Property “ev_out1”of type “UINT32”. Note: Event ID to switch toout1.

[2190] Property “ev_out2”of type “UINT32”. Note: Event ID to switch toout2.

[2191] Property “ev_toggle” of type “UINT32”. Note: Event ID to switchto the other output (i.e., out1 if out2 is selected and out2 if out1 isselected).

[2192] 35. Encapsulated Interactions

[2193] None.

[2194] 36. Specification

[2195] 37. Responsibilities

[2196] 1. Forward operations received on in to out1 or out2 based uponcontrol events received on ctl terminal.

[2197] 38. Theory of Operation

[2198] 38.1. State Machine

[2199] DM_MUX keeps state as to which outx terminal it is to forwardoperations received on its in terminal to. The state is controlled bythe events it receives on its ctl input. DM_MUX usesInterlockedExchange( ) to update its state. By default, DM_MUX's statespecifies that it is to forward operations to its out1 terminal.

ZP_SWP and ZP_SWPB—Property-Controlled Switches

[2200]FIG. 44 illustrates the boundary of the inventive DM_SWP part.

[2201]FIG. 45 illustrates the boundary of the inventive DM_SWPB part.

[2202] The property-controlled switches forward operations received onthe in input to one of their outputs (out1 or out2).

[2203] The selection of the outgoing terminal is controlled by the valueof a property that is modifiable while the part is active. When thevalue of property falls within a programmable range (defined by the min,max and mask properties), all events received on the in terminal areforwarded through the out1 terminal; otherwise they are forwardedthrough the out2 terminal.

[2204] ZP_SWPB is a bi-directional version of ZP_SWP. In the in to outdirection it operates exactly as ZP_SWP. It forwards all operationsreceived on its out1 and out2 terminals to the in terminal.

[2205] These parts provide a way to direct a flow of operations throughdifferent paths, depending on the value of a property that can bemodified dynamically.

[2206] 39. Boundary

[2207] 39.1. Terminals (ZP_SWP)

[2208] Terminal “in” with direction “in” and contract I_POLY. Note:v-table, infinite cardinality, unguarded. Operations received areforwarded to either out1 or out2.

[2209] Terminal “out1” with direction “out” and contract I_POLY. Note:Output for forwarded operations.

[2210] Terminal “out2”with direction “out” and contract I_POLY. Note:Output for forwarded operations.

[2211] 39.2. Terminals (ZP_SWPB)

[2212] Terminal “in” with direction “Bidir” and contract I_POLY. Note:v-table, infinite cardinality, unguarded. Operations received areforwarded to either out1 or out2.

[2213] Terminal “out1” with direction “Bidir” and contract I_POLY. Note:Output for forwarded operations. Operations received are forwarded toin.

[2214] Terminal “out2”with direction “Bidir” and contract I_POLY. Note:Output for forwarded operations. Operations received are forwarded toin.

[2215] 39.3. Properties

[2216] Property “val” of type “uint32”. Note: This property ismodifiable. Specifies the value used to determine which terminal theoperation is sent out. ZP_SWP/ZP_SWPB masks the value of this propertywith mask before comparing it to min and max. Default is 0.

[2217] Property “mask” of type “uint32”. Note: Bitwise mask ANDed withthe value of val property. before comparing it to min and max. Defaultis 0×FFFFFFFF (no change).

[2218] Property “min” of type “uint32”. Note: Lower boundary of the out1operations. This is the lowest integer value (inclusive) of the valproperty upon which all operations will be forwarded through out1terminal. Default is 0.

[2219] Property “max” of type “uint32”. Note: Upper boundary of the out1operations. This is the upper most integer value of the val property(inclusive) upon which all operations will be forwarded through out1terminal. Default is 0×FFFFFFFF.

[2220] 39.4. Events and Notifications

[2221] None.

[2222] 39.5. Special Events, Frames, Commands or Verbs

[2223] None.

[2224] 40. Encapsulated Interactions

[2225] None.

[2226] 41. Specification

[2227] 42. Responsibilities

[2228] 1. Forward operations received on in to out1 or out2 based thevalue of val property.

[2229] 2. (ZP_SWPB) Forward operations received on out1 and out2 to in.

ZP_CDM, ZP_CDMB—Connection Demultiplexers

[2230]FIG. 46 illustrates the boundary of the inventive DM_CDM part.

[2231]FIG. 47 illustrates the boundary of the inventive DM_CDMB part.

[2232] ZP_CDM and ZP_CDMB demultiplex operations received on their inputto one of the connections of their multiplexed output terminal.ZP_CDM(B) picks the ID of the connection to which the output is directedfrom a fixed offset in the operation bus. This offset and the data fieldsize are programmable as properties.

[2233] All operations received on the out terminal of ZP_CDMB areforwarded to the in terminal.

[2234] ZP_CDM and ZP_CDMB are parts that have “infinite cardinality”outputs, that is, outputs that can be connected to any number of inputs(another such part is the event bus—ZP_EVB).

[2235] ZP_CDM(B) can be used with structures that allow connectingmultiple parts to a single terminal and provide a known uniqueconnection ID for each established connection. Currently, the only suchstructure is provided by the part array (ZP_ARR)—when it creates andconnects a new part in the array, it automatically assigns the part IDto all connections established with that part.

[2236] 43. Boundary

[2237] 43.1. Terminals (ZP_CDM)

[2238] Terminal “in” with direction “in” and contract I_POLY. Note: Alloperations received on this terminal are forwarded to the out terminalconnection specified by the connection ID retrieved from operation bus.

[2239] Terminal “out” with direction “out” and contract I_POLY. Note:Output for forwarded operations. This terminal may be connected anddisconnected while the part is active. This is an “infinite cardinality”output—unlike a normal output terminal, it will accept any number ofsimultaneous connections.

[2240] 43.2. Terminals (ZP_CDMB)

[2241] Terminal “in” with direction “bi” and contract I_POLY. Note: Alloperations received on this terminal are forwarded to the out terminalconnection specified by the connection ID stored in the operation bus.

[2242] Terminal “out” with direction “bi” and contract I_POLY. Note: Alloperations received on this terminal are forwarded to the in terminal.This terminal may be connected and disconnected while the part isactive. This is an “infinite cardinality” bi-directional terminal—unlikea normal output or bi-directional terminal, it will accept any number ofsimultaneous connections.

[2243] 43.3. Properties

[2244] Property “id_offset” of type “uint32”. Note: Offset in operationbus where connection ID is stored. The default is 0.

[2245] Property “id_sz” of type “uint32”. Note: Size of the connectionID field in bytes. This property can have a value between 1 and 4inclusive. For sizes greater than 1, the byte order is assumed to be thenatural byte order of the host CPU. Important: if 2 or 4 is used, theid_offset must be a valid offset to a uint16 or uint32 structure field,respectively, aligned as necessary. If 1 or 3 is used, the offset can beanywhere in the bus. The default is 4.

[2246] Property “id_sgnext” of type “uint32”. Note: Boolean. If TRUE,connection IDs smaller than 4 bytes are sign extended. The default isFALSE.

[2247] 44. Specification

[2248] 45. Responsibilities

[2249] 1. Sign extend connection IDs with size less than 4 bytes whenid_sgnext property is TRUE.

[2250] 2. Enter the part guard when selecting the connection to ensurethat the terminal selection and activetime connection and disconnectionof the out terminal are serialized.

[2251] 3. Forward operations received on in to out by performing atomicselection on out terminal.

[2252] 4. Forward operations received on out to in.

[2253] 46. Theory of Operation

[2254] 46.1. Mechanisms

Performing Atomic Selection of ‘out’ Output

[2255] When ZP_CDM and ZP_CDMB receive a call on its in terminal, theyperform the following operations:

[2256] Enter the part guard using z_part_enter( )

[2257] Select the outgoing connection and obtain the pointer to theinterface

[2258] Leave the part guard suing z part leave( )

[2259] Make the outgoing call.

ZP_CMX—Connection Multiplexer/De-multiplexer

[2260]FIG. 48 illustrates the boundary of the inventive DM_CMX part.

[2261] ZP_CMX is a plumbing part that allows a single bi-directionalterminal to be connected to multiple distinguishable bi-directionalterminals and vice versa. Operations received on the bi terminal areforwarded out the mux terminal using a connection ID or an internallygenerated id_stored in the operation bus. Operations received on the muxterminal are forwarded out the bi terminal with ZP_CMX stamping theconnection id and optionally stamping an external connection contextinto the bus.

[2262] While ZP_CMX is active, it has the option to generate eventrequests out its ctl terminal when a connection is established and/ordissolved on its mux terminal. These requests provide the recipient withthe ability to assign an external context to the connection, which canbe used at a later time to process operation requests more efficiently.

[2263] ZP_CMX can be used to dispatch requests to one of many recipients(e.g., parts within a part array) or to connect multiple clients to asingle server.

[2264] Both of ZP_CMX's input terminals are unguarded and may be invokedat interrupt time.

[2265] 47. Boundary

[2266] 47.1. Terminals

[2267] Terminal “bi” with direction “bi” and contract I_POLY. Note:Operations received on this terminal are forwarded to the mux terminal.The connection is specified by a connection ID or an internallygenerated identifier stored in the operation bus.

[2268] Terminal “mux” with direction “bi” and contract I_POLY. Note:Operations received on this terminal are redirected to the bi terminal.ZP_CMX stamps a connection identifier and context into the operation busbefore forwarding the operation. This is an “infinite cardinality”output—unlike a normal output terminal, it will accept any number ofsimultaneous connections. This terminal may be connected anddisconnected while the part is active.

[2269] Terminal “ctl” with direction “Out” and contract I_DRAIN. Note:Event requests are generated out this terminal when the mux terminal isconnected and/or disconnected while ZP_CMX is active. This terminal mayremain unconnected and may not be connected while the part is active.

[2270] 47.2. Properties

[2271] Property “use_conn_id” of type “uint32”. Note: Boolean. WhenTRUE, ZP_CMX uses a connection ID to dispatch operations received on thebi terminal to the mux terminal. When FALSE, ZP_CMX uses an internallygenerated id stored in the operation bus to dispatch the call (fasterthan when using the connection id). Default is FALSE.

[2272] Property “id_offset” of type “uint32”. Note: Offset in operationbus for connection ID storage. When use_conn_id is FALSE, it is assumedthat id_offset specifies the offset of a_ctx field in the operation bus;otherwise it assumes that id_offset specifies the offset of a DWORDfield. The default is 0.

[2273] Property “conn_ctx_offset” of type “uint32”. Note: Offset inoperation bus where the connection context returned on ctl_connect_evrequest is stored for operations traveling from mux to bi. When thevalue is −1 and/or ZP_CMX's ctl terminal is not connected, no context isstored in the bus. The default is −1.

[2274] Property “ctl_connect_ev” of type “uint32”. Note: Event requestto generate out ctl when a connection on the mux terminal is established(connected). When the value is EV_NULL, no event is generated. Thedefault is EV_NULL.

[2275] Property “ctl_disconnect_ev” of type “uint32”. Note: Event togenerate out ctl when a connection on the mux terminal is dissolved(disconnected). When the value is EV_NULL, no event is generated. Thedefault is EV_NULL.

[2276] Property “ctl_bus_sz” of type “uint32”. Note: Size of event busfor connect and disconnect event requests generated out the ctlterminal. The value of this property must be at least as large toaccommodate storage for connection ID and context as specified thectl_id_offset and ctl_conn_ctx offset properties. The default is 0.

[2277] Property “ctl_id_offset” of type “uint32”. Note: Offset in eventbus for connection id storage. When use_conn_id is FALSE, it is assumedthat ctl_id_offset specifies the offset of a_ctx field in the operationbus; otherwise it is assumes that ctl_id_offset specifies the offset ofa DWORD field. When the value is −1, no ID is stored in the event bus.The default is −1.

[2278] Property “ctl_conn_ctx_offset” of type “uint32”. Note: Offset inevent bus for connection context storage. The recipient of thectl_connect_ev request provides the connection context and this contextis stamped into the bus of operations traveling from mux to bi. When thevalue is −1, no context is stored in the event bus. The default is −1.

[2279] 47.3. Events and Notifications

Terminal: ctl

[2280] Event Dir Bus Notes (ctl_connect_ev) out any ZP_CMX generatesthis request when a connection is established on its mux terminal. Theevent data may contain a connection identifier as specified by theuse_conn_id property. (ctl_disconnect_ev) out any ZP_CMX generates thisrequest when a connection is dissolved on its mux terminal. The eventdata may contain a connection identifier as specified by the use_conn_idproperty and or a connection context that was returned with thectl_connect ev request.

[2281] 48. Specification

[2282] 49. Responsibilities

[2283] 1. Forward operations received on bi to mux using the connectionID specified at id_offset when use_conn_id is TRUE.

[2284] 2. Forward operations received on bi to mux using an internallygenerated connection id_specified at id_offset when use_conn_id isFALSE.

[2285] 3. Stamp connection ID as specified by use_conn_id into bus onoperations traveling from mux to bi.

[2286] 4. Stamp connection context into bus of operations traveling frommux to bi if conn_ctx_offset is not −1.

[2287] 5. Generate event request out ctl terminal when a connection onmux terminal is established and the value of the ctl_connect_ev propertyis not EV_NULL.

[2288] 6. Generate event request out ctl terminal when a connection onmux terminal is dissolved and the value of the ctl_disconnect_evproperty is not EV_NULL.

[2289] 50. Use Cases

[2290]FIG. 49 illustrates an advantageous use of the inventive DM_CMXpart.

[2291] 50.1. Mux Terminal Connection

[2292] This use case describes the actions taken by ZP_CMX when itreceives a request to establish a connection on its mux terminal

[2293] 1. If the value of the ctl_connect_ev property is EV_NULL or thectl terminal is not connected, ZP_CMX establishes the connection andreturns.

[2294] 2. ZP_CMX allocates a ctl_connect_ev event request and if theuse_conn_id property is TRUE, stores the actual connection ID atctl_conn_id_offset; otherwise it stores an internally generatedconnection ID at ctl_conn_id_offset.

[2295] 3. ZP_CMS sends the event out the ctl terminal. If the returnstatus is not ST_OK, ZP_CMX fails the connect request with ST_REFUSE;otherwise ZP_CMX stores the connection context specified atctl_conn_ctx_offset into the data for the connection and returnssuccess.

[2296] 50.2. Mux Terminal Disconnection

[2297] This use case describes the actions taken by ZP_CMX when itreceives a request to dissolve a connection on its mux terminal.

[2298] 1. If the value of the ctl_disconnect_ev property is EV_NULL orthe ctl terminal is not connected, ZP_CMX dissolves the connection andreturns.

[2299] 2. ZP_CMX allocates a ctl_disconnect_ev event request and if theuse_conn_id property is TRUE, stores the actual connection ID atctl_conn_id_offset; otherwise it stores an internally generatedconnection ID at ctl_conn_id_offset. ZP_CMX also stores the connectioncontext that was returned on ctl_connect_ev at ctl_conn_ctx_offset.

[2300] 3. ZP_CMX sends the event out the ctl terminal. If the returnstatus is not ST_OK, ZP_CMX displays output to the debug console,dissolves the connection, and returns ST_OK; otherwise it simplydissolves the connection and returns ST_OK.

[2301] 50.3. De-multiplexing Operations

[2302] When ZP_CMX receives an operation on its bi terminal, it extractsthe connection identifier stored at id_offset in the operation bus andinterprets its value based on the value of its use_conn_id_property.ZP_CMX selects the appropriate connection on its mux terminal andforwards the operation without modification.

[2303] 50.4. Multiplexing Operations

[2304] When ZP_CMX receives on operation on its mux terminal, itperforms the following actions before forwarding the operation to its biterminal:

[2305] 1. Stamps the connection identifier at id_offset based on thevalue of its use conn id_property.

[2306] 2. Stamps the connection context associated with the connectionat conn_ctx_offset.

[2307] 3. Forwards the operation to the bi terminal.

[2308] 51. Typical Usage

[2309] 52. Using ZP_CMX to Allow Connection of Multiple Clients to aSingle Server

[2310] The following diagram illustrates how ZP_CMX can be used tomanage the connections between multiple clients and a single servercomponent. It is assumed that the server is able to handle multiplesessions at a time.

[2311] In the above scenario, ZP_CMX's use_conn_id property is set toFALSE. When a connection is established, ZP_CMX generates a connectrequest out its ctl terminal and the server returns a connection contextthat ZP_CMX is to stamp into the bus of operations received on thatconnection of the mux terminal. This gives the server the ability toquickly identify the client that originated an operation request itreceives.

[2312] When ZP_CMX receives a request on its mux terminal, it stamps theconnection identifier of the connection on which it received the callinto the operation bus and stamps the connection context provided by theserver and forwards the call out its bi terminal. When ZP_CMX receives arequest on its bi terminal from the server, it extracts the connectionidentifier from the operation bus, resolves the mux terminal connectionand forwards the operation.

[2313] When ZP_CMX receives a disconnect request, it generates an eventrequest out its ctl terminal to allow the server to perform anynecessary cleanup before the connection is dissolved.

[2314] 53. Using ZP_CMX with the Dynamic Structure Framework

[2315]FIG. 50 illustrates an advantageous use of the inventive DM_CMXpart.

[2316] The following diagram illustrates how ZP_CMX is used with theDynamic Structure Framework parts. Its functionality is similar to thatof ZP_CDMB.

[2317] In the above scenario, ZP_CMX's use conn id_property is set toTRUE. When a request is distributed to any of the part instances itcarries an identifier that uniquely specifies the actual recipient (partinstance (i.e., connection) ID). ZP_CMX extracts the identifier from theincoming request and dispatches the request to the corresponding partinstance.

DM_SPL, DM_BFL—Event Flow Splitters (Filters)

[2318]FIG. 51 illustrates the boundary of the inventive DM_SPL part.

[2319]FIG. 52 illustrates the boundary of the inventive DM_BFL part.

[2320] DM_SPL is a connectivity part. DM_SPL is designed to split theflow of events received on its in terminal into two: one going outthrough its out terminal and a second one going out through the auxterminal. The event split depends upon whether the incoming event is inrange defined by the ev_min and ev_max properties.

[2321] The event flow going through the out terminal (passing through)is considered to be the “main flow”—the majority of the events should gothere; the one going to the aux terminal is the “secondary flow”(auxiliary events)—these events are the generally exceptions from themain flow.

[2322] DM_SPL can be parameterized for the range of auxiliary events.This range is contiguous (cannot have “holes”) and is defined by theupper and the lower boundaries.

[2323] Hint: to construct a non-contiguous range: daisy-chain instancesof DM_SPL.

[2324] 54. Boundary

[2325] 54.1. Terminals (DM_SPL)

[2326] Terminal “in” with direction “In” and contract I_DRAIN. Note: Allinput events are received here and the main flow is forwarded to outterminal. The auxiliary flow is forwarded to aux terminal. The statusreturned is the one returned by the operation on the out or auxterminals depending to which terminal the event is forwarded to. If theterminal to which the event is forwarded is not connected, the operationwill return CMST_NOT_CONNECTED. Unguarded. Can be connected when thepart is active.

[2327] Terminal “out” with direction “Out” and contract I_DRAIN. Note:All main flow events received on in terminal are forwarded through here.Can be connected when the part is active.

[2328] Terminal “aux” with direction “Out” and contract I_DRAIN. Note:All auxiliary events are forwarded through here. Can be connected whenthe part is active.

[2329] 54.2. Terminals (DM_BFL)

[2330] Terminal “in” with direction “Plug” and contract I_DRAIN. Note:All input events are received here and the main flow is forwarded to outterminal. The auxiliary flow is forwarded to aux terminal. The statusreturned is the one returned by the operation on the out or auxterminals depending to which terminal the event is forwarded to. If theterminal to which the event is forwarded is not connected, the operationwill return CMST_NOT_CONNECTED. Unguarded. Can be connected when thepart is active.

[2331] Terminal “out” with direction “Plug” and contract I_DRAIN. Note:All main flow events received on in terminal are forwarded through here.Can be connected when the part is active.

[2332] Terminal “aux” with direction “Plug” and contract I_DRAIN. Note:All auxiliary events are forwarded through here. Can be connected whenthe part is active.

[2333] 54.3. Events and Notifications

[2334] All events received on in terminal are forwarded either to theout or to the aux terminals depending on whether they are consideredmain flow or auxiliary.

[2335] The range of auxiliary event IDs (contiguous) can be controlledby the outer scope by properties.

[2336] 54.4. Special Events, Frames, Commands or Verbs

[2337] None.

[2338] 54.5. Properties

[2339] Property “ev_min” of type “UINT32”. Note: Lower boundary of theauxiliary events. This is the lowest event ID value (inclusive) thatwill be considered auxiliary. If ev_min is EV_NULL, DM_SPL will considerall events auxiliary if their event ids are less than ev_max. If bothev_min and ev_max are EV_NULL, all events are considered auxiliary andsent through aux. Default: EV_NULL.

[2340] Property “ev_max” of type “UINT32”. Note: Upper boundary of theauxiliary events. If ev_max is EV_NULL, DM_SPL will consider all eventsauxiliary if their event ids are greater than ev_min. If both ev_min andev_max are EV_NULL, all events are considered auxiliary and sent throughaux. Default: EV_NULL.

[2341] 55. Encapsulated Interactions

[2342] None.

[2343] 56. Specification

[2344] 57. Responsibilities

[2345] 8. If event received on the in terminal is between ev_min andev_max, pass through the aux terminal (auxiliary flow).

[2346] 9. If event received on the in terminal is not between ev_min andev_max, pass through the out terminal (main flow).

[2347] 10. DM_BFL: Pass all events received from aux through in.

[2348] 11. DM_BFL: Pass all events received from out through in.

[2349] 58. Theory of Operation

[2350]FIG. 53 illustrates the internal structure of the inventive DM_BFLpart.

[2351] DM_SPL and DM_BFL split the event flow into two flows: main flowand auxiliary events. The main flow events are passed through the outterminal, the auxiliary to aux terminal.

[2352] The range of auxiliary events is controlled by properties.

DM_IFLT, DM_IFL TB—Filters by Integer Value

[2353]FIG. 54 illustrates the boundary of the inventive DM_IFLT part.

[2354]FIG. 55 illustrates the boundary of the inventive DM_IFLTB part.

[2355] DM_IFLT/DM_IFLTB are connectivity parts. DM_IFLT/DM_IFLTB aredesigned to split the flow of operations received on their in terminalsinto two: one going through their out terminals and a second one goingthrough their aux terminals. The operation split depends upon whetherthe incoming filter integer value (contained in the operation bus) is inrange defined by the min and max properties.

[2356] The operation flow going through the out terminal (passingthrough) is considered to be the “main flow”—the majority of theoperations should go here; the one going to the aux terminal is the“secondary flow” (auxiliary operations)—these operations are generallyexceptions from the main flow.

[2357] DM_IFLT/DM_IFLTB can be parameterized for the range of auxiliaryoperations. This range is contiguous (cannot have “holes”) and isdefined by lower and the upper boundaries (min and max propertiesrespectively).

[2358] Note: To construct a non-contiguous auxiliary range, daisy-chaininstances of DM_IFLT/DM_IFLTB.

[2359] 59. Boundary

[2360] 59.1. Terminals (DM_IFLT)

[2361] Terminal “in” with direction “In” and contract I_POLY. Note: Allinput operations are received here and the main flow is forwarded to theout terminal. The auxiliary flow is forwarded through the aux terminal.The status returned is the one returned by the operation on the out oraux terminals depending on which terminal the operation is forwarded to.If the terminal to which the operation is forwarded is not connected,the operation will return CMST_NOT_CONNECTED. This terminal isunguarded. DM_IFLT does not enter its guard at any time.

[2362] Terminal “out” with direction “Out” and contract I_POLY. Note:All main flow operations received on the in terminal are forwardedthrough here. The main flow are operations in which their buses filterinteger value falls outside of the range min . . . max.

[2363] Terminal “aux” with direction “Out” and contract I_POLY. Note:All auxiliary operations are forwarded through here. The auxiliary floware operations in which their buses filter integer value falls in therange of min . . . max.

[2364] 59.2. Terminals (DM_IFLTB)

[2365] Terminal “in” with direction “Plug” and contract I_POLY. Note:All input operations are received here and the main flow is forwarded tothe out terminal. The auxiliary flow is forwarded through the auxterminal. The status returned is the one returned by the operation onthe out or aux terminals depending on which terminal the operation isforwarded to. If the terminal to which the operation is forwarded is notconnected, the operation will return CMST_NOT_CONNECTED. This terminalis unguarded. DM_IFLTB does not enter its guard at any time.

[2366] Terminal “out” with direction “Plug” and contract I_POLY. Note:All main flow operations received on the in terminal are forwardedthrough here. The main flow are operations in which their buses filterinteger value falls outside of the range min . . . max. All operationsinvoked through this terminal are passed directly through in withoutmodification.

[2367] Terminal “aux” with direction “Plug” and contract I_POLY. Note:All auxiliary operations are forwarded through here. The auxiliary floware operations in which their buses filter integer value falls in therange of min . . . max. All operations invoked through this terminal arepassed directly through in without modification.

[2368] 59.3. Events and Notifications

[2369] All operations and events received on the in terminal areforwarded either to the out or to the aux terminals depending on whetherthey are considered main flow or auxiliary.

[2370] 13. If the operation filter integer value received on the interminal is not between min and max, pass operation through the outterminal (main flow).

[2371] 14. Before comparing the filter integer value with the min andmax properties, bitwise AND the filter value with the mask property.

[2372] 15. DM_IFLTB: Pass all operations received from aux through in.

[2373] 16. DM_IFLTB: Pass all operations received from out through in.

[2374] 63. Theory of Operation

[2375] DM_IFLT is a coded part.

[2376] DM_IFLTB is a static assembly

[2377] 63.1. Mechanisms

Filtering Operations

[2378] DM_IFLT and DM_IFLTB split the operation flow into two flows:main flow and auxiliary. The main flow operations are passed through theout terminal, the auxiliary to the aux terminal.

[2379] Which flow an operation belongs to is determined by the filterinteger value in the operation bus. DM_IFLT/DM_IFLTB extracts the filterinteger value from the operation bus using the offset property. Thisvalue is then ANDed (bitwise) with the mask property value. Theresulting value is then compared to the min and max values to checkwhich flow the operation belongs to.

[2380] The auxiliary flow are operations in which the filter integervalue falls into the range min . . . max. Operations in which the filterinteger value falls outside of the min . . . max range are consideredmain flow and are passed through the out terminal.

[2381] DM_IFLT/DM_IFLTB do not modify the operation bus received on thein terminal.

[2382] If a NULL bus is passed with the operation, the operation ispassed through the out terminal (main flow).

[2383] 63.2. Use Cases

Filtering Operations by Integer Value

[2384]FIG. 56 illustrates the internal structure of the inventiveDM_IFLT part.

[2385] 1. The structure in the above figure is created.

[2386] 2. DM_IFLT is parameterized with the following:

[2387] a. offset=offset of integer value in operation bus

[2388] b. mask=mask to AND integer value with

[2389] c. min=minimum boundary of auxiliary flow

[2390] d. max=maximum boundary of auxiliary flow

[2391] 3. The structure in the above figure is connected and activated.

[2392] 4. At some point, Part A invokes an operation through DM_IFLTpassing an operation bus that contains some integer value.

[2393] 5. DM_IFLT extracts the filter integer value from the operationbus passed with the call. DM_IFLT uses the offset property to extractthe value.

[2394] 6. DM_IFLT then ANDs the integer value with the value of the maskproperty.

[2395] 7. The resulting value is compared to the min and max properties.If the value is outside this range, the operation is forwarded throughthe out terminal and arrives in Part B (main flow). Otherwise, theoperation is forwarded through the aux terminal and arrives in Part C(auxiliary flow).

[2396] 8. Steps 4-7 may be executed many times.

Filtering Events by ID

[2397]FIG. 57 illustrates an advantageous use of the inventive DM_IFLTBpart.

[2398] 1. The structure in the above figure is created.

[2399] 2. DM_IFLT is parameterized with the following:

[2400] a. offset=offset of the event ID (offsetof (CMEVENT_HDR, id))

[2401] b. mask=mask to AND integer value with (0××FFFFFFFF)

[2402] c. min=minimum boundary of auxiliary flow events

[2403] d. max=maximum boundary of auxiliary flow events

[2404] 3. The structure in the above figure is connected and activated.

[2405] 4. At some point, Part A sends an event to DM_IFLT.

[2406] 5. DM_IFLT extracts the event ID from the event bus passed withthe call. DM_IFLT uses the offset property to extract the ID.

[2407] 6. DM_IFLT then ANDs the event ID with the value of the maskproperty leaving the event ID unchanged.

[2408] 7. The event ID is compared to the min and max properties. If theID is outside this range, the event is forwarded through the outterminal and arrives in Part B (main flow). Otherwise, the event isforwarded through the aux terminal and arrives in Part C (auxiliaryflow).

[2409] 8. Steps 4-7 may be executed many times.

DM_SFLT and DM_SFLT4—String Filters

[2410]FIG. 58 illustrates the boundary of the inventive DM_SFLT part.

[2411]FIG. 59 illustrates the boundary of the inventive DM_SFLT4 part.DM_SFLT and DM_SFLT4 filter incoming requests received on in bycomparing a string contained in the operation bus with a template(s)that the part is parameterized with. When a match is found, DM_SFLTforwards the operation to its aux terminal and DM_SFLT4 forwards theoperation to the aux terminal that corresponds to the template that wasmatched. When no match is found, the operation is forwarded to out.

[2412] The template can be one of four forms:

[2413] “”→Send all operations out out.

[2414] “String”→Match the string exactly.

[2415] “String*”→Match strings starting with specified string up to “*”.

[2416] “*”→Send all operations out aux.

[2417] 64. Boundary

[2418] 64.1. Terminals (DM_SFLT)

[2419] Terminal “in” with direction “In” and contract I_POLY. Note:v-table, infinite cardinality. All operations received are either passedto out terminal or aux terminal based on whether template is matched.This input is unguarded.

[2420] Terminal “out” with direction “Out” and contract I_POLY. Note:v-table, cardinality 1 Output for operations that do not match templatestring.

[2421] Terminal “aux” with direction “Out” and contract I_POLY. Note:v-table, cardinality 1 Output for operations that match template string.

[2422] 64.2. Terminals (DM_SFLT4)

[2423] Terminal “in” with direction “In” and contract I_POLY. Note:v-table, infinite cardinality. All operations received are either passedto out or to one of the aux terminals based on which template ismatched. This input is unguarded.

[2424] Terminal “out” with direction “Out” and contract I_POLY. Note:v-table, cardinality 1 Output channel for those operations where thestring does not match any of the templateX properties.

[2425] Terminal “aux1” with direction “Out” and contract I_POLY. Note:v-table, cardinality 1. Output channel for those operations that containa string matching template1 property.

[2426] Terminal “aux2” with direction “Out” and contract I_POLY. Note:v-table, cardinality 1 Output channel for those operations that containa string matching template2 property.

[2427] Terminal “aux3” with direction “Out” and contract I_POLY. Note:v-table, cardinality 1 Output channel for those operations that containa string matching template3 property.

[2428] Terminal “aux4” with direction “Out” and contract I_POLY. Note:v-table, cardinality 1 Output channel for those operations that containa string matching template4 property.

[2429] 64.3. Events and Notifications

[2430] None.

[2431] 64.4. Special Events, Frames, Commands or Verbs

[2432] None.

[2433] 64.5. Properties (DM_SFLT)

[2434] Property “offset” of type “UINT32”. Note: Offset of string inoperation bus. The default value is 0×00.

[2435] Property “by_ref” of type “UINT32”. Note: (boolean) If TRUE, thestring in the bus is by reference. If FALSE, the string is contained inthe bus. The default value is FALSE.

[2436] Property “ignore_case” of type “UINT32”. Note: (boolean) If TRUE,the string compare is not case-sensitive. The default is TRUE.

[2437] Property “template” of type “ASCIZ”. Note: Template to use whencomparing strings. The default value is “”.

[2438] 64.6. Properties (DM_SFLT4)

[2439] DM_SFLT4 has separate templates for each of its filter channels.All other properties are common to all channels.

[2440] Property “offset” of type “UINT32”. Note: Offset of string inoperation bus. The default value is 0×00.

[2441] Property “by_ref” of type “UINT32”. Note: (boolean) If TRUE, thestring in the bus is by reference. If FALSE, the string is contained inthe bus. The default value is FALSE.

[2442] Property “ignore_case” of type “UINT32”. Note: (boolean) If TRUE,the string compare is not case-sensitive. The default is TRUE.

[2443] Property “template1” of type “ASCIZ”. Note: Template to use whencomparing strings for operations to be forwarded to aux1. The default is“”.

[2444] Property “template2”of type “ASCIZ”. Note: Template to use whencomparing strings for operations to be forwarded to aux2. The default is“”.

[2445] Property “template3”of type “ASCIZ”. Note: Template to use whencomparing strings for operations to be forwarded to aux3. The default is“”.

[2446] Property “template4”of type “ASCIZ”. Note: Template to use whencomparing strings for operations to be forwarded to aux4. The default iscon.

[2447] 65. Encapsulated Interactions

[2448] None.

[2449] 66. Specification

[2450] 67. Responsibilities

[2451] 1. Forward operations that contain a string matching the templateproperty in its bus to the respective aux terminal.

[2452] 2. Forward all other operations to the out terminal.

[2453] 68. Theory of Operation

[2454] 68.1. State Machine

[2455] None.

[2456] 68.2. Mechanisms

Dereferencing String

[2457] If the by_ref property is FALSE, then the offset in the bus istreated as a byte location representing the first character of thestring. If the by_ref property is TRUE, then the offset is treated as aDWORD value that is converted into a character pointer.

[2458] 69. Dominant's Responsibilities (DM_SFLT4)

[2459] 69.1. Hard Parameterization of Subordinates

[2460] DM_SFLT4 does not perform any hard parameterization of itssubordinates.

[2461] 69.2. Distribution of Properties to the Subordinates Propertyname Type Distr To offset UINT3 bcas sfltX.offset 2 t by_ref UINT3 bcassfltX.by_ref 2 t ignore_case UINT3 bcas sfltX.ignore_case 2 t template1ASCIZ redir sflt1.template template2 ASCIZ redir sflt2.templatetemplate3 ASCIZ redir sflt3.template template4 ASCIZ redirsflt4.template

DM_IRPFLT—IRP Event Filter

[2462]FIG. 60 illustrates the boundary of the inventive DM_IRPFLT part.

[2463] DM_IRPFLT is designed to filter IRP events received on its interminal and send the filtered events to a separate terminal (aux). Theevents that are not subject to filtering are passed through to the outterminal.

[2464] The event flow going through the out terminal (passing through)is considered to be the “main flow”—the majority of the events should gothere; the one going to the aux terminal is the “secondary flow”(auxiliary events)—these events are generally exceptions from the mainflow.

[2465] DM_IRPFLT is parameterized with the function codes (both majorand minor) of the auxiliary IRP events. No more than one major and up to32 minor codes are supported. If no minor codes are specified, thefiltering is done only by major function code (the minor is ignored).

[2466] 70. Boundary

[2467] 70.1. Terminals

[2468] Terminal “in” with direction “In” and contract I_DRAIN. Note: Allinput events are received here and the main flow is forwarded to outterminal. The auxiliary events are forwarded to aux terminal. The statusreturned is the one returned by the operation on the out or auxterminals depending to which terminal the event is forwarded to. If theterminal to which the event is forwarded is not connected, the operationwill return CMST_NOT_CONNECTED. Unguarded. Can be connected when thepart is active.

[2469] Terminal “out” with direction “Out” and contract I_DRAIN. Note:All main flow events received on in terminal are forwarded through here.Can be connected when the part is active.

[2470] Terminal “aux” with direction “Out” and contract I_DRAIN. Note:All auxiliary events are forwarded through here. Can be connected whenthe part is active.

[2471] 70.2. Events and Notifications Received on the “in” TerminalIncoming Event Bus Notes EV_REQ_IRP B_EV_IRP Indicates that IRP needsprocessing.

[2472] 70.3. Properties

[2473] Property “irp_mj” of type “UCHAR”. Note: Major function code ofIRP events considered auxiliary. If 0×FF is specified, all events aresent to aux, without regard to other properties. Default: 0×FF.

[2474] Property “irp_mn[0.31]” of type “UCHAR”. Note: Array of IRP minorfunction codes. If irp_mj is not 0××FF, these codes are used todetermine whether an IRP event should be sent to considered Default:0×FF.

[2475] 71. Encapsulated Interactions

[2476] DM_IRPFLT calls the Windows I/O manager to retrieve IRP stacklocation.

[2477] 72. Specification

[2478] 73. Responsibilities

[2479] Pass main flow events to out terminal.

[2480] Pass auxiliary events to aux terminal

[2481] 74. Theory of Operation

[2482] 74.1. Main Data Structures

IO_STACK_LOCATION (system-defined)

[2483] This structure is used by the I/O Manager to pass the argumentsfor all driver functions (IRP_MJ_xxx).

[2484] 75. Notes

[2485] If DM_IRPFLT is parameterized to filter minor IRP codes and anIRP received on in has a minor code>=32, the IRP is simply passedthrough the out terminal without modification.

DM_BSP—Si-directional Splitter

[2486]FIG. 61 illustrates the boundary of the inventive DM_BSP part.

[2487] DM_BSP is a ClassMagic adapter part that makes it possible toconnect parts with bi-directional terminals to parts that haveunidirectional terminals.

[2488] All of DM_BSP terminals are I_POLY; thus DM_BSP can be insertedbetween any bus-based cdecl v-table connection (as long as there are nomore then 64 operations implemented on the counter terminals of DM_BSP).The terminals are also activetime and unguarded providing maximumflexibility in its use.

[2489] DM_BSP is inserted between a part with a bi-directional terminaland one or two parts with uni-directional terminals (one input and oneoutput). DM_BSP forwards operation calls between the parts. Operationsinvoked on its bi terminal are forwarded out through the out terminal.Operations invoked on its in terminal are forwarded out through the biterminal. This allows the parts connected to DM_BSP to communicate as ifthey were directly connected to each other.

[2490] The bus passed with the operation calls are not interpreted byDM_BSP.

[2491] 76. Boundary

[2492] 76.1. Terminals

[2493] Terminal “in” with direction “In” and contract I_POLY. Note:v-table, infinite cardinality, synchronous, unguarded, activetimeOperations invoked through this terminal are redirected out through thebi terminal. The bus passed with the call is not interpreted by DM_BSP.

[2494] Terminal “out” with direction “Out” and contract I_POLY. Note:v-table, cardinality 1, synchronous, unguarded, activetime Operationsinvoked through the bi terminal are redirected out through thisterminal. The bus passed with the call is not interpreted by DM_BSP.

[2495] Terminal “bi” with direction “Bidir (plug)” and contract I_POLY.Note: v-table, cardinality 1, synchronous, unguarded, activetimeOperations invoked through this terminal are redirected out through theout terminal. Calls received from the in terminal are redirected outthrough this terminal. The bus passed with the call is not interpretedby DM_BSP.

[2496] 76.2. Events and Notifications

[2497] None.

[2498] 76.3. Special Events, Frames, Commands or Verbs

[2499] None.

[2500] 76.4. Properties

[2501] None.

[2502] 77. Encapsulated Interactions

[2503] None.

[2504] 78. Specification

[2505] 79. Responsibilities

[2506] 1. Provide a compatible connection between a bi-directionalterminal and two uni-directional terminals (one input and one output).

[2507] 80. Theory of Operation

[2508] 80.1. State Machine

[2509] None.

[2510] 80.2. Main Data Structures

[2511] None.

[2512] 80.3. Mechanisms

Forwarding Operation Calls Between Parts

[2513]FIG. 62 illustrates an advantageous use of the inventive DM_BSPpart. DM_BSP makes it possible to connect a bi-directional terminal onone part to uni-directional terminals on other parts. DM_BSPaccomplishes this by forwarding the operations invoked on them to theappropriate part.

[2514] When DM_BSP receives a call through its in terminal, it redirectsthe call out through its bi terminal. When a call is received on the biterminal, it is redirected out through the out terminal. This mechanismprovides a compatible connection between the counter terminals of in,out and bi.

[2515] The bus received with the operation calls are not interpreted byDM_BSP.

[2516] 80.4. Use Cases

Connecting Two Parts to a Bi-directional Terminal Using DM_BSP

[2517] 1. In order to establish the connections in the diagram above,DM_BSP must be inserted between parts A, B and C.

[2518] 2. All the parts are constructed.

[2519] 3. Part A's bi terminal is connected to DM_BSP's bi terminal.

[2520] 4. DM_BSP's in terminal is connected to Part B's out terminal.

[2521] 5. DM_BSP's out terminal is connected to Part C's in terminal.

[2522] 6. All the parts are activated.

[2523] 7. At some point, Part A invokes an operation through its biterminal.

[2524] 8. DM_BSP receives the operation call on its bi terminal andredirects the call out through its out terminal.

[2525] 9. Part C receives the operation call on its in terminal andexecutes code for the operation. When the operation is complete, controlis returned back to Part A where the operation call originated.

[2526] 10. At some point, Part B invokes an operation through its outterminal.

[2527] 11. DM_BSP receives the operation call on its in terminal andredirects the call out through its bi terminal.

[2528] 12. Part A receives the operation call on its bi terminal andexecutes code for the operation. When the operation is complete, controlis returned back to Part B where the operation call originated.

[2529] 13. Steps 7-9 and 10-12 may be executed many times.

[2530] 14. All the parts are deactivated and destroyed.

Connecting a Part with Two Uni-directional Terminals to a Part with aBi-directional Terminal using DM_BSP

[2531]FIG. 63 illustrates an advantageous use of the inventive DM_BSPpart.

[2532] 1. In order to establish the connections in the diagram above,DM_BSP must be inserted between parts A and B.

[2533] 2. All the parts are constructed.

[2534] 3. Part A's bi terminal is connected to DM_BSP's bi terminal.

[2535] 4. DM_BSP's in terminal is connected to Part B's out terminal.

[2536] 5. DM_BSP's out terminal is connected to Part B's in terminal.

[2537] 6. All the parts are activated.

[2538] 7. The operation calls are forwarded in the same way as in thefirst use case.

[2539] 8. All the parts are deactivated and destroyed.

DM_DIS—Device Interface Splitter

[2540]FIG. 64 illustrates the boundary of the inventive DM_DIS part.

[2541] DM_DIS dispatches the operations on its in terminal to the out1and out2 terminals using a preview call to determine which of the twooutputs will accept the operations. The preview operation is the sameoperation as the one received on in, with the DIO_A_PREVIEW attributeset in the bus.

[2542] DM_DIS always calls both out1 and out2 on preview and interpretsthe return status as follows:

[2543] CMST_OK—the operation is acceptable, the part will process itsynchronously (i.e. will not return CMST_PENDING status).

[2544] CMST_SUBMIT—the operation is acceptable, the part claims theexclusive right to execute the operation. The operation may be processedasynchronously.

[2545] Other—the operation is not implemented.

[2546] Depending on the combination of returned statuses, DM_DIS callsout1, out2 or both with the preview flag cleared. The completedefinition of all combinations can be found in the boundary sectionbelow.

[2547] To allow DM_DIS to be chained, it handles specially incomingcalls on in with the preview attribute set—the preview is passed to out1or out2 and if any of them returns CMST_SUBMIT or CMST_OK, DM_DISreturns with this status and enters a “pass” state, expecting the nextcall to be the same operation with the preview attribute cleared. Thiscall will be passed transparently to the output(s) that originallyreturned CMST_SUBMIT or CMST_OK.

[2548] Incoming calls on out1 and out2 are forwarded transparently toin.

[2549] 81. Boundary

[2550] 81.1. Terminals

[2551] Terminal “in” with direction “Bidir” and contract In: I_DIO Out:I_DIO_C. Note: Multiplexed input/output. Incoming calls are dispatchedto out1 and out2. See the section “Requirements to Parts Connected toDM_DIS” for requirements to parts connected to this terminal.

[2552] Terminal “out1” with direction “Bidir” and contract In: I_DIO_COut: I_DIO. Note: Dispatched input/output #1. Calls to this terminal arepassed transparently to in. See the section “Requirements to PartsConnected to DM_DIS” for requirements to parts connected to thisterminal.

[2553] Terminal “out2”with direction “Bidir” and contract In: I_DIO_COut: I_DIO. Note: Dispatched input/output #2. Calls to this terminal arepassed transparently to in. See the section “Requirements to PartsConnected to DM_DIS” for requirements to parts connected to thisterminal.

[2554] 81.2. Events and Notifications

[2555] None.

[2556] 81.3. Special Events, Frames, Commands or Verbs

[2557] None.

[2558] 81.4. Properties

[2559] None.

[2560] 81.5. Requirements to Parts Connected to DM_DIS

Requirements to the Parts Connected to out1 and out2

[2561] The parts connected to the out1 and out2 terminals shouldcooperate with DM_DIS by responding to preview calls, so that DM_DIS candetermine how to distribute the calls on in to these parts.

[2562] When a part receives a call with the preview attribute set itshould determine if it will handle the operation and return one of thefollowing statuses:

[2563] CMST_OK—the part will handle the operation synchronously and itis OK for another part to handle the same operation (non-exclusiveclaim).

[2564] CMST_SUBMIT—the part will handle the operation eithersynchronously or asynchronously and it should be the only part to handlethe operation (exclusive claim).

[2565] Any error status—the part will not handle the operation.

[2566] A part performs the operations when it receives them with thepreview attribute cleared. If the operation was claimed non-exclusively(by returning CMST_OK on preview) the part should not returnCMST_PENDING. DM_DIS will detect this and display an error message onthe debug console.

Requirements to the Part Connected to in

[2567] A part connected to the in terminal may use two modes ofoperation:

[2568] normal—all calls are submitted with the “preview” attributecleared.

[2569] preview/submit—each call is submitted first with the previewattribute set, then (if the return status is CMST_OK or CMST_SUBMIT)with the preview attribute cleared. If DM_DIS is chained, there shouldbe no intervening calls to other operations between the preview and thesubmit call. The out1 and out2 terminals of DM_DIS itself conform tothese requirements, so that two or more instances of DM_DIS can bechained. If DM_DIS is not chained, there can be any number of operationcalls between the preview and the submit call.

[2570] A part connected to the in terminal is not required to keep usingonly one of the above modes—they can be interchanged on a per-callbasis.

[2571] 82. Encapsulated Interactions

[2572] None.

[2573] 83. Specification

[2574] 84. Responsibilities

[2575] Distribute calls on the in terminal to the out1 and out2terminals, use preview calls to determine which output(s) should handleeach call.

[2576] Allow connection of a part that uses preview calls (e.g., anotherinstance of DM_DIS) to be connected to the in terminal.

[2577] Pass calls from out1 and out2 transparently to in.

[2578] 85. Theory of Operation

[2579] 85.1. State Machine

[2580] None.

[2581] 85.2. Main Data Structures

[2582] None.

[2583] 85.3. Mechanisms

Preview Mechanism

[2584] DM_DIS uses this mechanism to determine which of the tworight-side terminals (out1 or out2) will handle an incoming call fromin. The following outcomes are defined:

[2585] Non-exclusive claim—one or more outputs will handle theoperation.

[2586] Asynchronous completion is not allowed.

[2587] Exclusive claim—only one output will handle the operation.Asynchronous completion is allowed.

[2588] Operation Rejected—none of the outputs will handle the operation.

[2589] Preview failed—conflicting claims.

[2590] DM_DIS performs the following steps:

[2591] Call out1 with the preview attribute set and save the returnstatus

[2592] Call out2 with the preview attribute set and save the returnstatus

[2593] Determine the preview outcome as follows:

[2594] one or both preview calls returned CMST_OK, none of them returnedCMST_SUBMIT—non-exclusive claim

[2595] one of the calls returned CMST_SUBMIT, the other returned anerror—exclusive claim

[2596] both calls returned an error—operation rejected

[2597] none of the above—preview failed

Call Distribution

[2598] This mechanism is used when DM_DIS receives the calls on in withthe preview attribute cleared:

[2599] The preview mechanism (as described above) is invoked todetermine the preview outcome.

[2600] If the outcome was “non-exclusive claim”—call the terminal(s)that returned CMST_OK, log an error if any of the calls returnsCMST_PENDING. The status returned in case both outputs are invoked isthe status from the second call if the first one returned CMST_OK andthe status from the first call otherwise.

[2601] If the outcome was “exclusive claim”—call the terminal thatreturned CMST_SUBMIT and return the status from that call.

[2602] If the outcome was “operation refused” return the status from thefirst preview.

[2603] If the statuses from preview indicate conflict, log an errormessage and return CMST_UNEXPECTED.

Preview Forwarding

[2604] This mechanism is used when DM_DIS is invoked on in with thepreview attribute set:

[2605] The preview mechanism (as described above) is invoked.

[2606] If the operation is rejected—return the status from the previewon out1.

[2607] If the preview failed—log an error and return CMST_UNEXPECTED.

[2608] Save the outcome, including which output(s) claimed theoperation.

[2609] Remember the operation that was invoked.

[2610] Set “pass” flag—this will cause the next operation on in to beprocessed as described in the next mechanism below.

[2611] Return CMST_OK if the claim was non-exclusive or CMST_SUBMIT ifthe claim was exclusive.

[2612] Submit Forwarding

[2613] This mechanism is used when DM_DIS has the “pass” flag set andthe in terminal is invoked on the same operation as the one that causedthe “pass” flag to be set:

[2614] 1. Clear the “pass” flag

[2615] 2. If the saved outcome was “non-exclusive claim”—call theterminal(s) that returned CMST_OK, log an error if any of the callsreturns CMST_PENDING. The status returned in case both outputs areinvoked is the status from the second call if the first one returnedCMST_OK and the status from the first call otherwise.

[2616] 3. If the saved outcome was “exclusive claim”—call the terminalthat returned CMST_SUBMIT and return the status from that call.

[2617] 85.4. Use Cases

Using DM_DIS to Arbitrate Between Two Parts that Implement Subsets ofI_DIO

[2618] If two parts implement non-intersecting subsets of I_DIO they canbe connected with DM_DIS to produce a single I_DIO terminal that exposesthe combined functionality of the two parts. To do this the two partsshould:

[2619] Check the preview attribute in the bus and return CMST_SUBMIT ifit is set and the part implements the requested operation orCMST_NOT_IMPLEMENTED otherwise.

[2620] Execute the operation when called with the preview attributecleared.

[2621] While processing a call with the preview attribute set, the partsshould not perform any action or state change under the assumption thatthey will receive the operation later, e.g. invoke complete operation onthe back channel of the I_DIO connection.

[2622] In this case DM_DIS will:

[2623] call the out1 terminal (with preview set)

[2624] call the out2 terminal (with preview set)

[2625] call out1 or out2 depending on which one returned CMST_SUBMIT andreturn the status from the operation

Chained Operation

[2626] The in terminal of DM_DIS may be connected to another part thatuses the preview/submit pattern used by DM_DIS itself.

[2627] Case 1 (no CMST_SUBMIT or CMST_OK)

[2628] DM_DIS receives a call on in with the preview attribute set.

[2629] DM_DIS calls both out1 and out2 with the operation, none of themreturns CMST_SUBMIT or CMST_OK

[2630] DM_DIS returns the status from out1.

[2631] Case 2 (one of the outputs returns CMST_SUBMIT)

[2632] DM_DIS receives a call on in with the preview attribute set

[2633] DM_DIS calls both out1 and out2 with the operation

[2634] the following information is saved:

[2635] set “pass” flag

[2636] which output returned CMST_SUBMIT (1 or 2)

[2637] which I_DIO operation was called

[2638] DM_DIS returns CMST_SUBMIT

[2639] When the next call is received on in; if not the same call as theone saved in step 3, DM_DIS resets the “pass” flag and processes thecall as normal (depending on the preview flag)

[2640] If the call is the same: the call is passed to the output (assaved from step 3).

[2641] Case 3 (one or both outputs returns CMST_OK)

[2642] receive a call on in with the preview attribute set

[2643] call both out1 and out2 with the operation

[2644] save the following information in self:

[2645] set “pass” flag

[2646] which output(s) returned CMST_OK

[2647] which I_DIO operation was called

[2648] return CMST_OK

[2649] receive a call on in; if not the same call as the one saved instep 3, reset the “pass” flag and process the call as normal (dependingon the preview flag)

[2650] If the call is the same: the call is passed to the output(s) (assaved from step 3). If one or both calls return CMST_PENDING, log anerror.

[2651] If only one output was called—DM_DIS returns the status from thatcall.

[2652] If both outputs were called—DM_DIS returns the status from thesecond call if the first one returned CMST_OK and the status from thefirst call otherwise.

Bi-directional Operation

[2653] Parts that implement the I_DIO interface can use the back channelof the I_DIO connection to complete the operations asynchronously. Thisis done by returning CMST_PENDING when the operation is submitted andinvoking I_DIO_C.complete operation on the back channel when theoperation is completed.

[2654] If a part connected to out1 or out2 has to complete an operationasynchronously, it should return CMST_SUBMIT on preview. This willguarantee that it will be the only part to execute the operation.

[2655] If DM_DIS receives CMST_PENDING status from a part that has notclaimed exclusive access (by returning CMST_SUBMIT on preview) it willlog an error message.

DM_IEV—Idle Generator Driven by Event

[2656]FIG. 65 illustrates the boundary of the inventive DM_IEV_part.

[2657] DM_IEV_generates idle events when it receives an external event.Upon receiving an event (EV_XXX) at its in terminal, DM_IEV_willcontinuously generate EV_IDLE events through idle until the sending ofthe EV_IDLE event returns CMST_NO_ACTION or CMST_BUSY, or until DM_IEVreceives anEV_(—REQ_DISABLE event from idle. The incoming event is not interpreted by DM_IEV; it is always forwarded through the out terminal.)

[2658] DM_IEV_has a property called idle first which controls when theidle generation should take place. If TRUE, the idle generation beginsbefore sending the incoming event through out; otherwise the idlegeneration happens after the event is sent.

[2659] DM_IEV keeps internal state indicating whether the idlegeneration is enabled or disabled. The idle generation becomes enabledor disabled when DM_IEV receives EV_REQ_ENABLE or EV_REQ_DISABLE,respectively. By default, the idle generation is enabled.

[2660] 86. Boundary

[2661] 86.1. Terminals

[2662] Terminal “in” with direction “In” and contract I_DRAIN. Note:v-table, infinite cardinality, floating, synchronous. This terminalreceives all the incoming events for DM_IEV.

[2663] Terminal “out” with direction “Out” and contract I_DRAIN. Note:v-table, cardinality 1, floating, synchronous. DM_IEV sends all eventsreceived from in out through this terminal. The events are notinterpreted by DM_IEV.

[2664] Terminal “idle” with direction “Bi” and contract I_DRAIN. Note:v-table, cardinality 1, synchronous. The EV_IDLE events are sent outthrough this terminal. EV_REQ_ENABLE and EV_REQ_DISABLE may be receivedthrough this terminal to control the idle generation.

[2665] 86.2. Events and Notifications Event Bus Notes <all> CMEVENT Allincoming events received from in _HDR terminal are passed through out/CMEvent terminal. Depending on the value of the idle_first property,DM_IEV will send the event out either before or after the idlegeneration.

[2666] 86.3. Special Events, Frames, Commands or Verbs Special IncomingEvent Bus Notes EV_REQ_ENABLE CMEVENT A request to start the idle_HDR/CME generation. It is received vent through the idle terminal. Thisrequest is sent by an idle consumer. Enabling and disabling are notcumulative. EV_REQ_DISABLE CMEVENT A request to stop the idle _HDR/CMEgeneration. It is received vent through the idle terminal. This requestis sent by an idle consumer. Enabling and disabling are not cumulative.

[2667] Special Outgoing Event Bus Notes EV_IDLE CMEVENT This event isgenerated _HDR/CME continuously either before vent or after sending theincoming event out through out (Depending on the setting of theidle_first property).

[2668] 86.4. Properties

[2669] Property “idle first” of type “UINT32”. Note: If TRUE,DM_IEV_will generate EV_IDLE events continuously before passing theincoming event to the out terminal. If FALSE, EV_IDLE feed will begenerated after passing the incoming event to the out terminal.Non-mandatory, Default is FALSE

[2670] 87. Encapsulated Interactions

[2671] None.

[2672] 88. Specification

[2673] 89. Responsibilities

[2674] 1. Generate EV_IDLE events until the idle generation is disabledor a CMST_NO_ACTION or CMST_BUSY event status is returned.

[2675] 2. Pass the incoming event through out terminal.

[2676] 3. Maintain the internal state of the idle generation.

[2677] DM_STP is a connectivity part. DM_STP consumes all events¹ thatcome to its in terminal and returns a status code specified in aproperty.

[2678] One of the important aspects of the DM_STP functionality isprocessing of self-owned events (CMEVT_A_SELF_OWNED). These events needspecial handling as the ownership of the memory allocated for themtravels with them.

[2679] DM_STP frees the self-owned events if the return status(specified by a property) is CMST_OK. For compatibility reasons DM_STPexposes a property, which can force freeing the event memory regardlessof the return status.

[2680] DM_PST and DM_PBS are I_POLY operation stoppers. These parts canbe used to stub any interface and return the appropriate status.

[2681] 1. Boundary

[2682] 1.1. Terminals (DM_STP)

[2683] Terminal “in” with direction “In” and contract I_DRAIN. Note: Allinput events are received here and consumed by the part. The statusreturned is the one specified by the ret_s property. Unguarded. Can beconnected when the part is active.

[2684] 1.2. Terminals (DM_BST)

[2685] Terminal “in” with direction “Plug” and contract I_DRAIN. Note:All input events are received here and consumed by the part. The statusreturned is the one specified by the ret_s property. Unguarded. Can beconnected when the part is active.

[2686] 1.3. Terminals (DM_PST)

[2687] Terminal “in” with direction “In” and contract I_POLY. Note: Alloperations received here and consumed by the part. The status returnedis the one specified by the ret_s property. Unguarded. Can be connectedwhen the part is active.

[2688] 1.4. Terminals (DM_PBS)

[2689] Terminal “in” with direction “Plug” and contract I_POLY. Note:All operations received here and consumed by the part. The statusreturned is the one specified by the ret_s property. Unguarded. Can beconnected when the part is active.

[2690] 1.5. Events and Notifications

[2691] All events received on in terminal are consumed.

[2692] The memory allocated for the self-owned events is freed if thereturn status (property) is CMST_OK.

[2693] If the value of the force_free property is TRUE then the memoryfor the self-owned events is freed regardless of the return status.

[2694] 1.6. Special Events, Frames, Commands or Verbs

[2695] None.

[2696] 1.7. Properties

[2697] Property “ret_s” of type “UINT32”. Note: Status to return on theraise operation. Default: CMST_OK.

[2698] Property “force_free” of type “UINT32”. Note: Set to TRUE to freeself-owned events without regard of what ret_s value is. Default: FALSE.

[2699] 2. Encapsulated Interactions

[2700] None.

[2701] 3. Specification

[2702] 4. Responsibilities

[2703] 17. DM_STP and DM_BST: Consume all events coming on in.

[2704] 18. DM_PST and DM_PBS: Stub all operations invoked through the interminal and return the appropriate status (specified by the ret_sproperty).

[2705] 19. Free the memory allocated for self-owned events if necessary.

[2706] 5. Theory of Operation

[2707] DM_STP consumes all events and returns a status specified by aproperty. The memory allocated for self-owned events is freed if any ofthe following conditions is satisfied:

[2708] a) the value of ret_s property is CMST_OK.

[2709] b) the value of the forcefree property is TRUE.

[2710] 5.1. Interior

[2711]FIG. 70 illustrates the internal structure of the inventive DM_BSTpart.

[2712]FIG. 71 illustrates the internal structure of the inventive DM_PSTpart.

[2713]FIG. 72 illustrates the internal structure of the inventive DM_PBSpart.

[2714] DM_STP is a coded part.

[2715] DM_BST, DM_PST and DM_PBS are static assemblies.

DM_UST, DM_DST—Universal and Drain Stoppers

[2716]FIG. 73 illustrates the boundary of the inventive DM_UST part.

[2717]FIG. 74 illustrates the boundary of the inventive DM_DST part.

[2718] DM_UST and DM_DST are connectivity parts. They are used toconsume all events/operations that come to their in and bi terminals andreturn a status code specified in a property. They can be used in eitherunidirectional or bi-directional connections. The terminals areactivetime and unguarded providing maximum flexibility in their use.

[2719] DM_UST can be used to consume either events or operations, whichis controlled through a property. For convenience, DM_DST is providedand can be used for event consumption instead of parameterizing DM_UST.

[2720] One of the important aspects of the functionality related toevents is the processing of self-owned events (CMEVT_A_SELF_OWNED).These events need special handling as the ownership of the memoryallocated for them travels with them.

[2721] DM_UST/DM_DST frees the self-owned events if the return status(specified by a property) is CMST_OK. For compatibility with older partsthey expose a property, which can force free the event memory regardlessof the return status.

[2722] 6. Boundary

[2723] 6.1. Terminals (DM_UST)

[2724] Terminal “in” with direction “In” and contract I_POLY. Note:v-table, activetime, infinite cardinality, synchronous Alloperations/events are received here and consumed by the part. Dependingon the value of the in_is_drain property, this terminal is expected tobe used for either events (I_DRAIN) or operation calls. The statusreturned is the one specified by the ret_s property. Unguarded. Can beconnected when the part is active.

[2725] Terminal “bi” with direction “Plug” and contract I_POLY. Note:v-table, activetime, cardinality 1, synchronous Same as the in terminaldescribed above except used for bi-directional connections. The outputside of bi is not used.

[2726] 6.2. Terminals (DM_DST)

[2727] Terminal “in” with direction “In” and contract I_DRAIN. Note:v-table, activetime, infinite cardinality, synchronous All events arereceived here and consumed by the part. The status returned is the onespecified by the ret_s property. Unguarded. Can be connected when thepart is active.

[2728] Terminal “bi” with direction “Plug” and contract I_DRAIN. Note:v-table, activetime, cardinality 1, synchronous Same as the in terminaldescribed above except used for bi-directional connections. The outputside of bi is not used.

[2729] 6.3. Events and Notifications

[2730] DM_UST (parameterized as an event stopper) and DM_DST accept anyincoming events and notifications on in or bi. They do not send out anyevents or notifications (the output side of bi is not used).

[2731] 6.4. Special Events, Frames, Commands or Verbs

[2732] None.

[2733] 6.5. Properties (DM_UST)

[2734] Property “in is drain” of type “UINT32”. Note: If TRUE, treat thein and bi terminals as I_DRAIN; otherwise as I_POLY. This propertydefines whether DM_UST is used to consume I_DRAIN events or interfaceoperation calls. Default: FALSE.

[2735] Property “ret_s” of type “UINT32”. Note: Status to return on theoperation invoked through the in or bi terminals. Default: CMST_OK.

[2736] Property “force_free” of type “UINT32”. Note: Set to TRUE to freeself-owned events without regard of what ret_s value is. Valid only ifin_is_drain property is TRUE. Default: FALSE.

[2737] 6.6. Properties (DM_DST)

[2738] Property “ret_s” of type “UINT32”. Note: Status to return on theraise operation. Default: CMST_OK.

[2739] Property “force_free” of type “UINT32”. Note: Set to TRUE to freeself-owned events without regard of what ret_s value is. Default: FALSE.

[2740] 7. Encapsulated Interactions

[2741] None.

[2742] 8. Specification

[2743] 9. Responsibilities

[2744] 20. DM_UST: Consume either all operations or events receivedthrough the in and bi terminals and return the appropriate status(specified by the ret_s property).

[2745] 21. DM_DST: Consume all events received through the in and biterminals and return the appropriate status (specified by the ret_sproperty).

[2746] 22. DM_UST and DM_DST: Free the memory allocated for self-ownedevents if necessary.

[2747] 10. Theory of Operation

[2748] DM_UST consumes all events/operations and returns a statusspecified by the ret_s property.

[2749] If using DM_UST or DM_DST to consume events, the memory allocatedfor self-owned events is freed if any of the following conditions aresatisfied:

[2750] a) the value of ret_s property is CMST_OK.

[2751] b) the value of the force_free property is TRUE.

[2752] 10.1. Interior

[2753]FIG. 75 illustrates the internal structure of the inventive DM_DSTpart.

[2754] DM_UST is a coded part.

[2755] DM_DST is a static assembly.

[2756] 10.2. Hard Parameterization of Subordinates (DM_DST) PartProperty Value UST in_is_drain TRUE

[2757] 10.3.

[2758] 10.4. Distribution of Properties to the Subordinates (DM_DST)Property Name Type Dist To ret_s UINT32 redir UST.ret_s force_freeUINT32 redir UST.force_free

Event Consolidators DM_ECSB and DM_ECS—Event Consolidators

[2759]FIG. 76 illustrates the boundary of the inventive DM_ECS part.

[2760]FIG. 77 illustrates the boundary of the inventive DM_ECSB part.

[2761] DM_ECSB recognizes a pair of events—the “open” event and the“close” event. DM_ECSB forwards the first “open” event received on in toout and either counts and consumes or rejects subsequent “open” eventsdepending on how it is parameterized.

[2762] DM_ECSB consumes all “close” events except for the last one,which it forwards to its out terminal. If DM_ECSB receives a “close”event and it has not received an “open” event, it returns a status withwhich it has been parameterized. DM_ECSB forwards all unrecognizedevents received on its in terminal to its out terminal and visa versa.

[2763] DM_ECSB is able to handle events that are completedasynchronously. DM_ECS is the unidirectional version of DM_ECSB. Itassumes that all events are handled synchronously.

[2764] 1. Boundary

[2765] 1.1. Terminals (DM_ECSB)

[2766] Terminal “in” with direction “Bidir (plug)” and contract I_DRAIN(v-table). Note: Input for unconsolidated “open” and “close” events andoutput for completion_events.

[2767] Terminal “out” with direction “Bidir (plug)” and contract I_DRAIN(v-table). Note: Output for consolidated “open” and “close” events andinput for completion_events.

[2768] 1.2. Terminals (DM_ECS)

[2769] Terminal “in” with direction “In” and contract I_DRAIN (v-table).Note: Input for unconsolidated “open” and “close” events.

[2770] Terminal “out” with direction “Out” and contract I_DRAIN(v-table). Note: Output for consolidated “open” and “close” events.

[2771] 1.3. Events and Notifications

[2772] DM_ECSB recognizes two specific events: ev_open and ev_close. Theevent IDs for these two events are specified as properties and aredescribed in the table below. Incoming Event Bus Notes ev_openCMEVENT_(—) Synchronous or HDR or Asynchronous “open” extended eventreceived on in terminal or an asynchronous completion event received onthe out terminal (DM_ECSB). The event ID is specified as a property onDM_ECSB. ev_close CMEVENT_(—) Synchronous or HDR or Asynchronous “close”extended event received on in terminal or an asynchronous completionevent received on the out terminal (DM_ECSB). The event ID is specifiedas a property on DM_ECSB. all others CMEVENT_(—) All events received onin HDR or are forwarded to out. extended DM_ECSB: unrecognized eventsreceived on out are forwarded to in if DM_ECSB is not expecting toreceive a completion event; otherwise the event is refused.

[2773] 1.4. Special Events, Frames, Commands or Verbs

[2774] None.

[2775] 1.5. Properties

[2776] Property “ev_open” of type “UINT32”. Note: ID of the “open”event. The default is EV_(—REQ_ENABLE)

[2777] Property “ev_close” of type “UINT32”. Note: ID of the “close”event. the default is EV_(—REQ_DISABLE)

[2778] Property “cplt_s offset” of type “UINT32”. Note: Offset in eventbus for completion status. If the value is 0—do not use. The default is0×00 for DM_ECS and 0×0 C for DM_ECSB.

[2779] Property “underflow_s” of type “UINT32”. Note: Status to returnwhen a “close” event is received and there is has been no “open” eventreceived. The default is CMST_NO_ACTION.

[2780] Property “reject” of type “UINT32”. Note: (boolean)When TRUE,DM_ECS and DM_ECSB will reject nested “open” events. The default isFALSE.

[2781] Property “reject_s” of type “UINT32”. Note: Status to return whenrejecting nested “open” events. The default is CMST_REFUSE.

[2782] Property “busy_s” of type “UINT32”. Note: Status to return if an“open” or “close” event is received on in and there is already a pending“open” or “close” request. The default is CMST_BUSY.

[2783] Property “force_free” of type “UINT32”. Note: (boolean)Set toTRUE to free self-owned events without regard to what the return statusis. The default is FALSE.

[2784] 2. Encapsulated Interactions

[2785] None.

[2786] 3. Specification

[2787] 4. Responsibilities

[2788] 1. Maintain counter that is incremented when an “open” event isreceived and decremented when a “close” event is received.

[2789] 2. Forward first “open” event and last “close” event received onin to out; consume or reject all others based on parameterization.

[2790] 3. Forward all non-recognized events received on in to outwithout modification.

[2791] 4. Refuse subsequent “open”/”close” events when there is asynchronous/asynchronous event request pending.

[2792] 5. (DM_ECSB) Forward all non-recognized events received on out toin without modification.

[2793] 5. Theory of Operation

[2794] 5.1. State Machine

[2795] DM_ECSB implements a small state machine that it uses to handlepending events. Regardless of whether the events complete synchronouslyor asynchronously, it is possible to get into the following situation:while the first enable is pending, a second one comes. Since DM_ECSBdoesn't know whether the first one will succeed, it doesn't know whetherto pass it or not. Another situation is where the “close” event comeswhile the “open” event is still pending.

[2796] Note that if the events complete synchronously and the secondrequest comes in another thread, it will be blocked until the firstevent completes and then it will be processed as usual. The problemexists only if the events may complete asynchronously or the secondevent may come in the same thread in which the first one is pending(feedback).

[2797] To simplify the above situations, DM_ECSB rejects subsequent“open”/“close” events, when it has an event pending, with CMST_BUSY.

[2798] The state machine has the following states:

[2799] S_IDLE DM_ECSB is waiting for an “open” or “close” event.

[2800] S_SYNC_PENDING DM_ECSB is currently processing a synchronous“open” or “close” event.

[2801] S_ASYNC_PENDING_OPE DM_ECSB is currently

[2802] N processing an asynchronous “open” event and is waiting for thecompletion event.

[2803] S_ASYNC_PENDING_CLO DM_ECSB is currently

[2804] SE processing an asynchronous “close” event and is waiting forthe completion event.

[2805] 5.2. Mechanisms

Handling Pending Synchronous Events

[2806] When DM_ECSB receives a synchronous “open” or “close” event, andit is in the S_IDLE state and it does not consume/reject the event, ittransitions its state to S_SYNC_PENDING and forwards the request to itsoutput. When the operation has completed, DM_ECSB increments/decrementsits counter, moves its state back to S_IDLE and returns the status fromthe call.

[2807] If DM_ECSB receives a synchronous “open” or “close” event and itis in any of its S_XXX_PENDING states, it consumes the request andreturns the value of its busy_s property.

Handling Pending Asynchronous Events

[2808] When DM_ECSB receives a asynchronous “open” or “close” event, andit is in the S_IDLE state and it does not consume/reject the event, ittransitions its state to S_ASYNC_PENDING_XXX depending on the event andforwards the request to its output. If the call fails with status otherthan CMST_PENDING, DM_ECSB moves back to the S_IDLE state. If theoperation returned success and DM_ECSB's cplt_offset_s property is not0, it checks the completion status in the event bus. If it is notCMST_OK or CMST_PENDING, it moves back to the S_IDLE state and returnsthe status from the call; otherwise it remains in theS_ASYNC_PENDING_XXX state.

[2809] When DM_ECSB receives the completion event on its out terminalfor the pending event, it increments/decrements its counterappropriately, moves back to the S_IDLE state, and forwards the call toits in terminal.

[2810] If DM_ECSB receives an asynchronous “open” or “close” event andit is in any of its S_XXX_PENDING states, it fails the request andreturns the value of its busy_s property.

Indicators DM_IND—Indicator

[2811]FIG. 78 illustrates the boundary of the inventive DM_IND part.

[2812] DM_IND is used to trace the program flow through partconnections. DM_IND can be inserted between any two parts that have aunidirectional connection. When an operation is invoked on its interminal, DM_IND dumps the operation bus fields to the debug console bydescriptor. The operation is then forwarded to the out terminal. DM_INDdoes not modify the operation bus.

[2813] In order to interpret the operation bus, DM_IND must beparameterized with a pointer to an interface bus descriptor (bus_descpproperty). This descriptor specifies the format strings and operationbus fields to be dumped. The format string syntax is the same as the oneused in printf. The order of the fields in the descriptor needs tocorrespond to the order of the format specifiers in the format string.The descriptor may have any number of format strings and fields. Theonly limitation is that the total size of the formatted output cannotexceed 512 bytes. Please see the reference of your C or C++ run-timelibrary for a description of the format string specifiers.

[2814] DM_IND's dump output can be disabled by setting the enabledproperty to FALSE. When disabled, all operation calls are directlypassed through out, allowing control over multiple indicators in asystem. By default, DM_IND will always dump the operation bus accordingto its descriptor.

[2815] Each DM_IND instance may be uniquely identified. Before dumpingthe operation bus to the debug console, DM_IND will optionally identifyitself by outputting the name property (if not “”). This property can beset to any string; it is not interpreted by DM_IND.

[2816] 1. Boundary

[2817] 1.1. Terminals

[2818] Terminal “in” with direction “In” and contract I_POLY. Note:v-table, cardinality 1, floating, synchronous. All operations invokedthrough this terminal are passed through the out terminal. DM_IND doesnot modify the operation bus passed with the call.

[2819] Terminal “out” with direction “Out” and contract I_POLY. Note:v-table, cardinality 1, floating, synchronous. All operations invoked onthe in terminal are passed through this terminal. If this terminal isnot connected, DM_IND will fail the call with CMST_NOT_CONNECTED afterdisplaying the data. DM_IND does not modify the operation bus passedwith the call.

[2820] 1.2. Events and Notifications

[2821] None.

[2822] 1.3. Special Events, Frames, Commands or Verbs

[2823] None.

[2824] 1.4. Properties

[2825] Property “name” of type “ASCIIZ”. Note: This is the instance nameof DM_IND. It is displayed first in the debug output. Default is “”.

[2826] Property “enabled” of type “UINT32”. Note: If TRUE, DM_IND willdump the operation bus to the debug console according to its descriptor(bus_descp). If FALSE, DM_IND will not output anything to the debugconsole. It will just pass the operation call through out terminal.Default is TRUE.

[2827] Property “bus_descp” of type “UINT32”. Note: This is the pointerto the operation bus descriptor used by DM_IND. It describes the outputformat and the operation bus fields. This property must be set andcontain a valid descriptor pointer. This property is mandatory.

[2828] 2. Encapsulated Interactions

[2829] None.

[2830] 3. Specification

[2831] 4. Responsibilities

[2832] 1. Dump the values of the operation bus fields to the debugconsole according to the bus descriptor.

[2833] 2. Pass all operation calls on the in terminal out through theout terminal.

[2834] 5. Theory of Operation

[2835] 5.1. State Machine

[2836] None.

[2837] 5.2. Main Data Structures

[2838] DM_IND uses an operation bus descriptor (supplied from outside bythe property bus_descp). This descriptor specifies the format stringsand operation bus fields. The descriptor is an array of the followingstructure: // entry types enum CMINT_ET { CMIND_ET_NONE = 0, // no entrytype specified CMIND_ET_FORMAT = 1, // format string CMIND_ET_VALUE = 2,// value field CMIND_ET_REF = 3, // reference field CMIND_ET_END = 4, //end of table }; // operation bus table entry typedef structCMIND_BUS_ENTRY { dword et ; // entry type [CMIND_ET_XXX] dword et_ctx ;// entry type specific context dword sz ; // size of storage }CMIND_BUS_ENTRY;

[2839] The entry type specifies the type of the field. There are threeentry types:

[2840] 1. format string—The format string describes the way the outputwill look on the debug console. This entry contains a formatting string,identical to the one used by printf (i.e., “Int=%d, Char=%c\n”).

[2841] 2. value field—The value field represents an operation bus fieldthat contains a value. An example would be a character, an integer or apointer to a string.

[2842] 3. reference field—The reference field represents an operationbus field that should be passed by reference (address of). Use this typeto print the value of a string that is contained in the bus. Excludingstrings, DM_IND can dump only the value of a pointer, not the datareferenced by the pointer.

[2843] The entry type context is either an offset to the storage of anoperation bus field or a string reference. If the entry type is a formatstring, the context is a pointer to a string describing the outputformat. If the entry type is a value or reference field, the context isthe offset of the field within the operation bus.

[2844] The size is only used by the value field entry type. Thisrepresents the size of the storage of the field within the operationbus.

[2845] DM_IND defines several macros that aid in defining the operationbus descriptor. The macros are defined below: Macro DescriptionBUS_DUMP_DESC Begin declaration of operation bus (name) descriptorEND_BUS_DUMP_(—) End declaration of operation bus DESC descriptorind_format(str) Define a format string entry ind_by_val(bus,field)Define a value field ind_by_ref(bus,field) Define a reference field

[2846] DM_IND defines several macros that aid in parameterizing theindicator. The macros are defined below:

[2847] Note: These macros must follow immediately the DM_IND part entryin the SUBORDINATES table.

[2848] // macros used for hard parameterization of the indicator MacroDescription ind_dump(name) Hard parameterizes the “bus_descp” propertyto be the address of the declared bus descriptor ind_disable Hardparameterizes the “enabled” property to FALSE ind_name(name) Hardparameterizes the “name” property to name

[2849] Here is an example of defining an operation bus descriptor:

[2850] BUS_DUMP_DESC (B_EXAMPLE_BUS)

[2851] ind_format (“Integer=%d, Character=%c, String=%s”)

[2852] ind_format (“Pointer=%Ix, Buffer”%s“\n”)

[2853] ind_by_val (B_EXAMPLE_BUS, integer)

[2854] ind_by_val (B_EXAMPLE_BUS, character)

[2855] ind_by_val (B_EXAMPLE_BUS, string)

[2856] ind_by_val (B_EXAMPLE_BUS, pointer)

[2857] ind_by_ref (B_EXAMPLE_BUS, buffer)

[2858] END_BUS_DUMP_DESC

[2859] Here is the definition of B_EXAMPLE_BUS:

[2860] BUS (B_EXAMPLE_BUS)

[2861] uint integer;

[2862] char character;

[2863] char *string;

[2864] void *pointer;

[2865] char buffer[120];

[2866] END_BUS

[2867] Here is an example of hard parameterizing DM_IND in thesubordinates table:

[2868] SUBORDINATES (PART_NAME)

[2869] part (ind1, DM_IND)

[2870] ind_name (“My example indicator name”)

[2871] ind_dump (B_EXAMPLE_BUS)

[2872] ind_disable

[2873] // other parts . . .

[2874] END_SUBORDINATES

[2875] 5.3. Mechanisms

Dumping an Operation's Bus Contents

[2876] DM_IND will assemble all output into one buffer and then dump theentire buffer to the debug console.

[2877] To dump the operation bus, DM_IND executes two passes through theoperation bus descriptor. During the first pass, DM_IND will collect allformat strings and concatenate them. During the second pass, DM_IND willcollect all the field values and will assemble them in a separatebuffer. DM_IND will then use wvsprintf to format the final output stringand output it to the debug console.

[2878] The size of the formatted output cannot exceed 512 bytes. If itdoes there will be a memory overwrite by wvsprintf. DM_IND will attemptto detect overwrites but it cannot prevent them. If an overwrite isdetected DM_IND will print a warning to the debug console.

[2879] 5.4. Use Cases

Tracing/debugging the Program Flow Through Connections

[2880] 1. Insert DM_IND between a part A and part B. Part A's outputterminal is connected to DM_IND's in terminal and Part B's inputterminal is connected to DM_IND's out terminal.

[2881] 2. Fill out a bus descriptor to get the desired output formattingfor the bus.

[2882] 3. Parameterize DM_IND with a pointer to the bus descriptor andan instance name (instance name is optional).

[2883] 4. Activate DM_IND.

[2884] 5. As Part A invokes operations through its output terminalconnected to DM_IND, the operation calls come to DM_IND's in terminal.DM_IND displays its instance name (if name is not “”) and dumps theformatted operation bus contents to the debug console.

[2885] 6. The operation call is passed out through DM_IND's out terminaland the operation on part B's input terminal is invoked. The returnstatus from the operation call is returned to the caller.

[2886] Note As both terminals of DM_IND are of type I_POLY, care shouldbe taken to use only compatible terminals; DM_IND may not always checkthat the contract ID is the same.

DM_CTR—Call Tracer

[2887]FIG. 79 illustrates the boundary of the inventive DM_CTR part.

[2888] DM_CTR is used to trace the program execution through partconnections. DM_CTR can be inserted between any two parts that have aunidirectional connection.

[2889] When an operation is invoked on its in terminal, DM_CTR dumps thecall information to either the debug console or by sending an EV_MESSAGEevent through the con terminal (if connected). The operation is thenforwarded to the out terminal. When the call returns, DM_CTR outputs thecall information and the return status of the operation. DM_CTR does notmodify the operation bus.

[2890] DM_CTR's output can be disabled through a property. Whendisabled, all operations are directly passed through out, allowing forselective tracing through a system.

[2891] Each DM_CTR instance is uniquely identified. Before dumping theoperation bus, DM_CTR will identify itself. This identification includesthe DM_CTR unique instance id, recurse count of the operation and otheruseful information. This identification may also include the value ofthe name property.

[2892] Note As both terminals of DM_CTR are of type I_POLY, care shouldbe taken to use only compatible terminals; DM_CTR may not always checkthat the contract ID is the same.

[2893] 6. Boundary

[2894] 6.1. Terminals

[2895] Terminal “in” with direction “In” and contract I_POLY. Note:v-table, infinite cardinality, floating, synchronous. All operationsinvoked through this terminal are passed through the out terminal.DM_CTR does not modify the bus passed with the operation.

[2896] Terminal “out” with direction “Out” and contract I_POLY. Note:v-table, cardinality 1, floating, synchronous. All operations invoked onthe in terminal are passed through this terminal. If this terminal isnot connected, DM_CTR will return with CMST_NOT_CONNECTED afterdisplaying the call information. DM_CTR does not modify the bus passedwith the operation.

[2897] Terminal “con” with direction “Out” and contract I_DRAIN. Note:v-table, cardinality 1, floating, synchronous. If connected, DM_CTRsends an EV_MESSAGE event containing the call information through thisterminal. In this case no debug output is printed.

[2898] 6.2. Events and Notifications Outgoing Event Bus Notes EV_MESSAGEB_EV_MSG DM_CTR sends an EV_MESSAGE event containing the callinformation through the con terminal (if connected). This allows theoutput to be sent to mediums other than the debug console.

[2899] 6.3. Special Events, Frames, Commands or Verbs

[2900] None.

[2901] 6.4. Properties

[2902] Property “name” of type “ASCIIZ”. Note: This is the instance nameof DM_CTR. It is the first field in the call information. If the name is“”, the instance name printed is “DM_CTR”. Default is “”.

[2903] Property “enabled” of type “UINT32”. Note: If TRUE, DM_CTR willdump the call information to either the debug console or as anEV_MESSAGE event sent through

[2904] Property “dump_before” of type “UINT32”. Note: If TRUE, DM_BSDwill dump the operation bus before passing the call through the outterminal. Default is FALSE.

[2905] Property “dump_after” of type “UINT32”. Note: If TRUE, DM_BSDwill dump the operation bus after passing the call through the outterminal. Default is FALSE.

[2906] 12. Encapsulated Interactions

[2907] None.

[2908] 13. Specification

[2909] 14. Responsibilities

[2910] 3. Dump the values of the operation bus fields to an outputmedium according to the bus descriptor.

[2911] 4. Pass all operation calls on the in terminal out through theout terminal.

[2912] 15. Theory of Operation

[2913] 15.1. State Machine

[2914] None.

[2915] 15.2. Main Data Structures

[2916] DM_BSD uses an operation bus descriptor (supplied from outside bythe property bus_descp). This descriptor specifies the format stringsand operation bus fields. The descriptor is an array of the followingstructure: // entry types enum DM_BSD_ET { DM_BSD_ET_NONE = 0, // noentry type specified DM_BSD_ET_FORMAT = 1, // format stringDM_BSD_ET_VALUE = 2, // value field DM_BSD_ET_REF = 3, // referencefield DM_BSD_ET_END = 4, // end of table }; // operation bus table entrytypedef struct DM_BSD_BUS_ENTRY { dword et ; // entry type[DM_BSD_ET_XXX] dword et_ctx ; // entry type specific context dword sz ;// size of storage } DM_BSD_BUS_ENTRY;

[2917] The entry type specifies the type of the field. There are threeentry types:

[2918] 4. format string—The format string describes the way the outputwill look. This entry contains a formatting string, identical to the oneused by printf (i.e., “Int=%d, Char=%c\n”).

[2919] 5. value field—The value field represents an operation bus fieldthat contains a value. An example would be a character, an integer or apointer to a string.

[2920] 6. reference field—The reference field represents an operationbus field that should be passed by reference (address of). Use this typeto print the value of a string that is contained in the bus. Excludingstrings, DM_BSD can dump only the value of a pointer, not the datareferenced by the pointer.

[2921] The entry type context is either an offset to the storage of anoperation bus field or a string reference. If the entry type is a formatstring, the context is a pointer to a string describing the outputformat. If the entry type is a value or reference field, the context isthe offset of the field within the operation bus.

[2922] The size is only used by the value field entry type. Thisrepresents the size of the storage of the field within the operationbus.

[2923] DM_BSD defines several macros that aid in defining the operationbus_descriptor. The macros are defined below: Macro DescriptionDM_BSD_BUS_DUMP_(—) Begin declaration of operation DESC(name) busdescriptor DM_BSD_END_BUS_(—) End declaration of operation DUMP_DESC busdescriptor dm_bsd_format(str) Define a format string entrydm_bsd_by_val(bus,field) Define a value field dm_bsd_by_ref(bus,field)Define a reference field

[2924] DM_BSD defines several macros that aid in parameterizing theindicator. The macros are defined below:

[2925] Note: These macros must follow immediately the DM_BSD part entryin the SUBORDINATES table. Macro Description dm_bsd_dump Hardparameterizes the “bus_descp” (name) property to be the address of thedeclared bus descriptor dm_bsd_disable Hard parameterizes the “enabled”property to FALSE dm_bsd_name Hard parameterizes the “name” (name)property to name dm_bsd_dump_(—) Hard parameterizes the “dump_before”before property to TRUE dm_bsd_dump_(—) Hard parameterizes the“dump_after” after property to TRUE

[2926] Here is an example of defining an operation bus descriptor:

[2927] DM_BSD_BUS_DUMP_DESC (B_EXAMPLE_BUS)

[2928] dm_bsd_format (“Integer=%d, Character=%c, String=%s”)

[2929] dm_bsd_format (“Pointer=%Ix, Buffer “%s”\n”)

[2930] dm_bsd_by_val (B_EXAMPLE_BUS, integer)

[2931] dm_bsd_by_val (B_EXAMPLE_BUS, character)

[2932] dm_bsd_by_val (B_EXAMPLE_BUS, string)

[2933] dm_bsd_by_val (B_EXAMPLE_BUS, pointer)

[2934] dm bsd by ref (B EXAMPLE BUS, buffer)

[2935] DM_BSD_END_BUS_DUMP_DESC

[2936] Here is the definition of B_EXAMPLE_BUS:

[2937] BUS (B_EXAMPLE_BUS)

[2938] uint integer;

[2939] char character;

[2940] char*string;

[2941] void * pointer;

[2942] char buffer[120];

[2943] END_BUS

[2944] Here is an example of hard parameterizing DM_BSD in thesubordinates table:

[2945] SUBORDINATES (PART_NAME)

[2946] part (ind1, DM_BSD)

[2947] dm_bsd_name (“My example bus dumper name”)

[2948] dm_bsd_dump (B_EXAMPLE_BUS)

[2949] dm_bsd_dump_before

[2950] dm_bsd_dump_after dm_bsd_disable

[2951] // other parts . . .

[2952] END_SUBORDINATES

[2953] 15.3. Mechanisms

Dumping an Operation's Bus Contents

[2954] DM_BSD will assemble the output into a buffer and then dump theentire buffer either to the debug console or by sending an EV_MESSAGEevent through the con terminal.

[2955] DM_BSD determines where to send the output by checking if the conterminal is connected on activation. If con is connected, DM_BSD willsend EV_MESSAGE events that contain the output. This enables the outputto be sent to a different medium other than the debug console (i.e.serial port). If con is not connected, the output will always go to thedebug console.

[2956] To dump the operation bus, DM_BSD executes two passes through theoperation bus descriptor. During the first pass, DM_BSD will collect allformat strings and concatenate them. During the second pass, DM_BSD willcollect all the field values and will assemble them in a separatebuffer. DM_BSD will then use wvsprintf to format the final outputstring.

[2957] The size of the formatted output cannot exceed 512 bytes. If itdoes there will be a memory overwrite by wvsprintf. DM_BSD will attemptto detect overwrites but it cannot prevent them. If an overwrite isdetected DM_BSD will print a warning to the debug console.

[2958] The format of the output is:

[2959] <instance name> [#<instance id>] (call

[2960] #<re-enterance call #>) <pre/post>\n

[2961] <dump of operation bus>\n

[2962] .\n

[2963] Here is an example:

[2964] MyBSDDump [#31378912] (call #5) pre\n

[2965] My Operation bus dump:\n

[2966] bus.integer=10\n

[2967] bus.char=‘A’\n

[2968] .\n Field Description instance name Unique name of DM_BSDsupplied by user (name property). instance id Unique instance id ofDM_BSD (assembled by DM_BSD). re-enterance Value that uniquelyidentifies the call # operation call in case of recursive calls to otheroperations. This makes it easy to trace recursive operation calls.pre\post This indicates whether the dump of the bus is before or afterthe operation call passed through out. dump of This is the contents ofthe operation bus operation bus as defined by the bus descriptor(bus_descp property).

[2969] 15.4. Use Cases

Tracing/debugging the Program Flow Through Connections (output sent tothe debug console)

[2970] 7. Insert DM_BSD between part A and part B. Part A's outputterminal is connected to DM_BSD's in terminal and Part B's inputterminal is connected to DM_BSD's out terminal.

[2971] 8. Parameterize DM_BSD with an instance name and bus descriptor(instance name is optional).

[2972] 9. Activate DM_BSD.

[2973] 10. As Part A invokes operations through its output terminalconnected to DM_BSD, the operation calls come to DM_BSD's in terminal.DM_BSD dumps the formatted operation bus contents to the debug console.

[2974] 11. The operation call is passed out through DM_BSD's outterminal and the operation on part B's input terminal is invoked. Thereturn status from the operation call is returned to the caller.

Tracing/debugging the Program Flow Through Connections (output sent toother mediums)

[2975] 1. Insert DM_BSD between part A and part B. Part A's outputterminal is connected to DM_BSD's in terminal and Part B's inputterminal is connected to DM_BSD's out terminal.

[2976] 2. Connect DM_BSD's con terminal to Part C's in terminal.

[2977] 3. Parameterize DM_BSD with an instance name and operation names(instance and operation names are optional).

[2978] 4. Activate DM_BSD.

[2979] 5. As Part A invokes operations through its output terminalconnected to DM_BSD, the operation calls come to DM_BSD's in terminal.DM_BSD sends an EV_MESSAGE event through the con terminal containing theformatted operation bus contents.

[2980] 6. Part C receives the EV_MESSAGE event and sends the bus dumpout a serial port to another computer.

[2981] 7. The operation call is passed out through DM_BSD's out terminaland the operation on part B's input terminal is invoked. The returnstatus from the operation call is returned to the caller.

Synchronization Parts Details Desynchronizers DM_FDSY—FundamentalDesynchronizer

[2982]FIG. 81 illustrates the boundary of the inventive DM_FDSY part.

[2983] DM_FDSY de-couples the flow of control from the operation flow, amechanism known as desynchronization. DM_FDSY desynchronizes alloperations received on its in terminal. The operation buses are notinterpreted by DM_FDSY. DM_FDSY enqueues the operation and its bus; thequeue keeps the operations in the same order as they are received. AsEV_IDLE/EV_PULSE events are received on its ctl input, DM_FDSY dequeuesall the pending operations and sends them through the out terminal (oneoperation is dequeued for each EV_IDLE/EV_PULSE event received). Thesize of the queue used by DM_FDSY is dynamic and may be limited by aproperty called queue_sz.

[2984] DM_FDSY issues EV_REQ_ENABLE and EV_REQ_DISABLE requests throughits ctl terminal in order to control the pulse generation. The issuingof these requests can be disabled through the property disable_ctl_req.

[2985] 1. Boundary

[2986] 1.1. Terminals

[2987] Terminal “in” with direction “In” and contract I_POLY. Note:v-table, infinite cardinality, floating, synchronous. DM_FDSYdesynchronizes the operations received on this terminal. The bus passedwith the operation call is not interpreted by DM_FDSY. This terminal isunguarded. DM_FDSY does not enter its guard at any time.

[2988] Terminal “out” with direction “Out” and contract I_POLY. Note:v-table, cardinality 1, synchronous. DM_FDSY sends all desynchronizedqueued operations out through this terminal (when it receivesEV_IDLE/EV_PULSE events from ctl). The bus passed with the operationcall is not interpreted by DM_FDSY and is passed directly through theout terminal. The outgoing operations are in the same order as they werereceived from in.

[2989] Terminal “ctl” with direction “Plug” and contract I_DRAIN. Note:v-table, cardinality 1, synchronous. EV_IDLE/EV_PULSE events arereceived through this terminal so DM_FDSY can dequeue operations andsend them through the out terminal (one operation is dequeued for eachEV_IDLE/EV_PULSE event received). DM_FDSY generates pulse enable/disablerequests through this terminal (unless the disable_ctl_req property isTRUE). This terminal is unguarded. DM_FDSY does not enter its guard atany time.

[2990] 1.2. Events and Notifications Incoming Event Bus Notes EV_RESETCMEVENT_(—) This event is received on the ctl HDR terminal. In response,DM_FDSY flushes its operation queue. No operations are invoked throughthe out terminal. EV_IDLE CMEVENT_(—) This event is received on the ctlHDR terminal. In response, DM_FDSY dequeues an operation and invokes itthrough out. If there are no elements on the queue, DM_FDSY will returnCMST_NO_ACTION even if disable_ctl_req property is set to TRUE. EV_PULSECMEVENT_(—) This event is the same as EV_IDLE. HDR

[2991] Outgoing Event Bus Notes EV_REQ_(—) CMEVENT_(—) DM_FDSY sendsthis request through ENABL HDR ctl when an operation is invoked on thein terminal and the operation queue was empty. DM_FDSY sends this eventonly if disable_ctl_req property is FALSE. EV_REQ_(—) CMEVENT_(—)DM_FDSY sends this request through DISABLE HDR ctl if the operationqueue is empty (after receiving EV_IDLE/EV_PULSE and dequeueing the lastoperation). DM_FDSY sends this event only if disable_ctl_req property isFALSE.

[2992] 1.3. Special Events, Frames, Commands or Verbs

[2993] None.

[2994] 1.4. Properties

[2995] Property “queue_sz” of type “UINT32”. Note: This is the number ofevents that the operation queue can hold. If 0, the queue will extenditself when it gets full (the number of operations the queue can hold islimited only by available memory). Default is 0.

[2996] Property “disable ctl_req” of type “UINT32”. Note: Boolean. IfFALSE, DM_FDSY sends requests through ctl to enable/disable the pulsegeneration when needed. If TRUE, requests are never sent through ctl.Default is FALSE.

[2997] Property “ok_stat” of type “UINT32”. Note: This specifies thestatus that DM_FDSY returns on calls through in if the operation wassuccessfully enqueued. This status is also used to determine ifoperations passed through out succeeded. Default is CMST_OK.

[2998] Property “disable diag” of type “UINT32”. Note: Boolean. Thisdetermines whether DM_FDSY prints debug output indicating that a callthrough ctl or out failed. A call through ctl fails if the return statusis not equal to CMST_OK. A call through out fails if the return statusis not equal to ok_stat. This property affects only the checked build ofDM_FDSY. Default is FALSE.

[2999] 2. Specification

[3000] 3. Responsibilities

[3001] 1. Desynchronize all incoming operations received through the interminal and return the appropriate status.

[3002] 2. When an EV_IDLE/EV_PULSE event is received from the ctlterminal, dequeue and invoke an operation through the out terminal.

[3003] 3. Do not interpret or modify the operation bus passed withoperation calls received on the in terminal.

[3004] 4. Depending on the value of the disable_ctl_req property,generate enable/disable requests through ctl when needed.

[3005] 5. Depending on the value of disable_diag, print debug output ifoperations invoked through out or ctl fail (checked builds only).

[3006] 4. Theory of Operation

[3007] 4.1. Main Data Structures

[3008] DM_FDSY uses a DriverMagic queue to store all desynchronizedoperations and their buses.

[3009] 4.2. Mechanisms

Desynchronization of Incoming Operations

[3010] DM_FDSY desynchronizes all operations invoked through the interminal. DM_FDSY enqueues the operation and its bus and returns to thecaller. The return status is ok_stat (if enqueing of the operationsucceeded; otherwise a failure status is returned). DM_FDSY thenrequests pulse generation (if the disable_ctl_req property is FALSE andthe queue was empty) by sending an EV_REQ_ENABLE event through the ctlterminal.

[3011] For each EV_IDLE/EV_PULSE event received from the ctl terminal,DM_FDSY dequeues one operation and invokes it through out. If thedisable_ctl_req property is FALSE and the queue is empty, DM_FDSYrequests to disable the pulse generation by sending an EV_REQ_DISABLEevent through ctl.

[3012] The operation bus received on the in terminal is not interpreted,modified or valchked by DM_FDSY. The operation bus passed through out isthe exact same bus received with the operation invoked through the interminal.

[3013] All enable/disable pulse generation events sent through ctl areallocated on the stack and sent with the CMEVT_A_SYNC_ANY andCMEVT_A_SELF_CONTAINED attributes.

Event Handling on the ctl Terminal

[3014] All self-owned events received on the ctl terminal are freed byDM_FDSY only if the processing of that event is successful (CMST_OK isreturned).

[3015] All unrecognized events are not processed by DM_FDSY and aCMST_NOT_SUPPORTED status is returned.

[3016] If an EV_IDLE or EV_PULSE event is received when the operationqueue is empty, DM_FDSY returns CMST_NO_ACTION.

[3017] 4.3. Use Cases

Desynchronizing Operations

[3018] 1. The counter terminal of in invokes an operation through in andthe call is received by DM_FDSY.

[3019] 2. Unless the disable_ctl_req property is TRUE, an EV_REQ_ENABLEevent is sent through the ctl terminal.

[3020] 3. The operation is enqueued and the flow of control is returnedto the caller. The return status is ok_stat.

[3021] 4. Steps 1 and 3 may be repeated several times.

[3022] 5. DM_FDSY receives an EV_IDLE/EV_PULSE event from its ctlterminal.

[3023] 6. DM_FDSY dequeues one operation and invokes it through the outterminal passing the same operation bus as received on the in terminal.

[3024] 7. If the return status from the operation call is not equal took_stat and disable_diag is FALSE, DM_FDSY prints debug outputindicating that the operation call failed.

[3025] 8. Steps 5 through 7 are repeated many times.

[3026] 9. If the disable_ctl_req property is FALSE an EV_REQ_DISABLEevent is sent through the ctl terminal to stop the pulse generation(when the operation queue becomes empty).

[3027] 5. Notes

[3028] 1. DM_FDSY assumes that buses passed with operations invokedthrough the in terminal are not allocated on the caller's stack.

[3029] 2. DM_FDSY does not interpret, modify or valchk the operationbuses received on the in terminal. The bus passed through the outterminal is exactly the same as the bus received on the in terminal (itis the original bus pointer).

DM_DSY—Desynchronizer

[3030]FIG. 82 illustrates the boundary of the inventive DM_DSY part.

[3031] DM_DSY desynchronizes and forwards events received at its ininput. The input event will be desynchronized only if the input event'sattributes specify that it may be distributed asynchronously and it isself-contained. If the input event is not self-owned, DM_DSY will outputa copy of the event.

[3032] 6. Boundary

[3033] 6.1. Terminals

[3034] Terminal “in” with direction “In” and contract I_DRAIN. Note:v-table, infinite cardinality, synchronous This terminal receives allthe incoming events for DM_DSY.

[3035] Terminal “out” with direction “Out” and contract I_DRAIN. Note:v-table, cardinality 1, synchronous DM_DSY sends all de-synchronizedevents out through this terminal.

[3036] 6.2. Events and Notifications Incoming Event Bus Notes EV_XXXCMEVENT_(—) All incoming events on in are de- HDR/ synchronized and sentout through out. CMEvent

[3037] 6.3. Outgoing Event Bus Notes EV_XXX CMEVENT_(—) All incomingevents on in are de- HDR/ synchronized and sent out through out. CMEvent

[3038] 6.4. Special Events, Frames, Commands or Verbs

[3039] None.

[3040] 6.5. Properties

[3041] None.

[3042] 7. Encapsulated Interactions

[3043] None.

[3044] 8. Specification

[3045] 9. Responsibilities

[3046] 2. Desynchronize all incoming events received from in and sendthem out through out.

[3047] 10. Theory of Operation

[3048] 10.1. State Machine

[3049] None.

[3050] 10.2. Main Data Structures

[3051] None.

[3052] 10.3. Mechanisms

Desynchronization of Incoming Events

[3053] DM_DSY desynchronizes an input event by first examining the eventattributes. If the event can be distributed only synchronously or is notself-contained, DM_DSY will not desynchronize the event and return errorstatus. If the event is not self-owned, DM_DSY will allocate a new eventcontrol block and copy the input event into it.

[3054] Next, DM_DSY uses a built-in ClassMagic mechanism todesynchronize the event and returns to the caller. At a later time,usually when the application or the system is idle, DM_DSY passes theevent through its out output.

[3055] Note The desynchronized event may be distributed in threaddifferent than the one that posted it. This may impose additionallimitations if thread-local storage is used.

[3056] 10.4. Use Cases

Desynchronization of Incoming Events that are Not Self-owned

[3057] 1. The counter terminal of in sends an event to DM_DSY.

[3058] 2. DM_DSY receives the event.

[3059] 3. If the event is not desynchronizable, the call fails; DM_DSYreturns CMST_REFUSE.

[3060] 4. DM_DSY allocates a new event control block and copies theinput event into it. Note that the input event may have been allocatedon the stack or on the heap; DM_DSY handles these cases correctly.

[3061] 5. The event is enqueued and the control is returned back to thecaller.

[3062] 6. When DM_DSY receives control from the ClassMagicdesynchronizer, the event is sent through the out output synchronously.

[3063] 7. The counter terminal of out processes the event and returnscontrol back to DM_DSY.

[3064] 8. DM_DSY returns control back to the ClassMagic desynchronizer.

DM_DSYR—Desynchronizer for Requests

[3065]FIG. 83 illustrates the boundary of the inventive DM_DSYR part.

[3066] DM_DSYR de-couples the flow of control from the request flow, amechanism known as desynchronization. DM_DSYR desynchronizes allrequests received on its in terminal. DM_DSYR enqueues the request; thequeue keeps the requests in the same order as they are received. Foreach EV_IDLE or EV_PULSE event received on its ctl input, DM_DSYRdequeues one pending request and sends it through the out terminal. Thesize of the queue used by DM_DSYR is dynamic and may be limited by aproperty called queue_sz.

[3067] DM_DSYR issues EV_REQ_ENABLE and EV_REQ_DISABLE requests throughits ctl terminal in order to control the pulse generation. The issuingof these requests can be disabled through the property disable_ctl_req.

[3068] DM_DSYR expects that the incoming request can completeasynchronously. If the request does not have the CMEVT_A_ASYNC_CPLTattribute set, DM_DSYR fails the request with CMST_REFUSE.

[3069] DM_DSYR assumes that the requests are not allocated on thecaller's stack.

[3070] 11. Boundary

[3071] 11.1. Terminals

[3072] Terminal “in” with direction “Plug” and contract I_DRAIN. Note:v-table, infinite cardinality, floating, synchronous. DM_DSYRdesynchronizes the requests received on this terminal. This terminal isunguarded. DM_DSYR does not enter its guard at any time.

[3073] Terminal “out” with direction “Plug” and contract I_DRAIN. Note:v-table, cardinality 1, synchronous. DM_DSYR sends all desynchronizedqueued requests out through this terminal (when it receivesEV_IDLE/EV_PULSE events from ctl). The outgoing requests are in the sameorder as they were received from in.

[3074] Terminal “ctl” with direction “Plug” and contract I_DRAIN. Note:v-table, cardinality 1, synchronous. EV_IDLE/EV_PULSE events arereceived through this terminal so DM_DSYR can dequeue requests and sendthem through the out terminal (one operation is dequeued for eachEV_IDLE/EV_PULSE event received). DM_DSYR generates pulse enable/disablerequests through this terminal (unless the disable_ctl_req property isTRUE). This terminal is unguarded. DM_DSYR does not enter its guard atany time.

[3075] 11.2. Events and Notifications Incoming Event Bus Notes EV_RESETCMEVENT_(—) This event is received on the ctl HDR terminal. In response,DM_DSYR flushes its request queue. No requests are sent through the outterminal. EV_IDLE CMEVENT_(—) This event is received on the ctl HDRterminal. In response, DM_DSYR dequeues a request and sends it throughout. If there are no elements on the queue, DM_DSYR will returnCMST_NO_ACTION even if disable_ctl_req property is set to TRUE. EV_PULSECMEVENT_(—) This event is the same as EV_IDLE. HDR

[3076] Outgoing Event Bus Notes EV_REQ_(—) CMEVENT_(—) DM_DSYR sendsthis request through ENABLE HDR ctl when a request is received on the interminal and the request queue was empty. DM_DSYR sends this event onlyif disable_ctl_req property is FALSE. EV_REQ_(—) CMEVENT_(—) DM_DSYRsends this request through DISABLE HDR ctl if the request queue is empty(after receiving EV_IDLE/EV_PULSE and dequeueing the last request).DM_DSYR sends this event only if disable_ctl_req property is FALSE.

[3077] 11.3. Special Events, Frames, Commands or Verbs

[3078] None.

[3079] 11.4. Properties

[3080] Property “queue_sz” of type “UINT32”. Note: This is the number ofevents that the request queue can hold. If 0, the queue will extenditself when it gets full (the number of requests the queue can hold islimited only by available memory). This property is redirected to theFDSY subordinate. Default is 0.

[3081] Property “disable_ctl_req” of type “UINT32”. Note: Boolean. IfFALSE, DM_DSYR sends requests through ctl to enable/disable the pulsegeneration when needed. If TRUE, requests are never sent through ctl.This property is redirected to the FDSY subordinate. Default is FALSE.

[3082] Property “disable_diag” of type “UINT32”. Note: Boolean. Thisdetermines whether DM_DSYR prints debug output indicating that a callthrough ctl or out failed. A call through ctl fails if the return statusis not equal to CMST_OK. A call through out fails if the return statusis not equal to CMST_PENDING. This property affects only the checkedbuild of DM_DSYR. This property is redirected to the FDSY subordinate.Default is FALSE.

[3083] Property “cplt_s_offs” of type “UINT32”. Note: Offset in bytes ofthe completion status in the request bus. This property is redirected tothe ACT subordinate. Mandatory.

[3084] 12. Encapsulated Interactions

[3085] None.

[3086] 13. Specification

[3087] 14. Responsibilities

[3088] Desynchronize all incoming requests received through the interminal and return the appropriate status.

[3089] If the CMEVT_A_ASYNC_CPLT attribute is not set on the incomingrequest fail with CMST_REFUSE.

[3090] When an EV_IDLE/EV_PULSE event is received from the ctl terminal,dequeue and invoke a request through the out terminal.

[3091] Depending on the value of the disable_ctl_req property, generateenable/disable requests through ctl when needed.

[3092] Depending on the value of disable_diag, print debug output ifrequests sent through out or ctl fail (checked builds only).

[3093] 15. Internal Definition

[3094]FIG. 84 illustrates the internal structure of the inventiveDM_DYSR part.

[3095] 16. Theory of Operation

[3096] DM_DSYR is an assembly built entirely of DriverMagic parts.

[3097] DM_DSYR is based mainly on DM_FDSY. Please see the DM_FDSY datasheet for more information.

[3098] Requests received on in pass through bsp_in and go to iflt. Ifthe request does not have the CMEVT_A_ASYNC_CPLT attribute set, ifltsends the request out through aux where its consumed by stp. stp returnsCMST_REFUSE and the status is propagated back to the original caller.

[3099] Requests that can complete asynchronously are forwarded to fdsywhere they are enqueued in the request queue. fdsy returns CMST_PENDINGto indicate that the request will be processed asynchronously.

[3100] Requests received on in are continuously enqueued by fdsy untilDM_DSYR receives an EV_IDLE or EV_PULSE event on its ctl terminal. Theseevents are forwarded to fdsy. In response, fdsy dequeues one request andsends it out through the out terminal. The request is then passed tobsp_act and forwarded to act.

[3101] Requests received by act are forwarded through the out terminal.If the request is completed asynchronously, the completion event issimply forwarded through bsp_act, bsp_in and then through DM_DSYR's interminal. If the request is completed synchronously, act creates acompletion event, stores the completion status in the event, and sendsit out through bsp_act. Thus, all requests send through DM_DSYR aregurenteed to be completed with a completion event sent through the backchannel of DM_DSYR's in terminal.

[3102] 17. Subordinate's Responsibilities

[3103] 17.1. DM_BSP—Bi-directional Splitter

[3104] Split event flow between a single bidirectional interface and aninput/output interface pair.

[3105] 17.2. DM_IFLT—Filter by Integer Value

[3106] If the operation filter integer value received on the in terminalis between min and max, pass operation through the aux terminal(auxiliary flow).

[3107] If the operation filter integer value received on the in terminalis not between min and max, pass operation through the out terminal(main flow).

[3108] 17.3. DM_STP—Operation Stopper

[3109] 1. Consume all operations received on its terminal.

[3110] 17.4. DM_FDSY—Fundamental Desynchronizer

[3111] 2. Desynchronize all incoming operations received through the interminal and return the appropriate status.

[3112] 17.5. DM_ACT—Asynchronous Completer

[3113] 3. Transform synchronous completion of an outgoing event intoasynchronous completion of the incoming event that generated the former.

[3114] 18. Dominant's Responsibilities

[3115] 18.1. Hard Parameterization of Subordinates Subordinate PropertyValue iflt offset offsetof (CMEVENT_HDR, attr) iflt maskCMEVT_A_ASYNC_CPLT iflt min 0 iflt max 0 stp ret_s CMST_REFUSE fdsyok_stat CMST_PENDING

[3116] 18.2. Distribution of Properties to the Subordinates PropertyName Type Dist To queue_sz UINT32 Redir fdsy.queue_sz disable_ctl_reqUINT32 Redir fdsy.disable_ctl_req disable_diag UINT32 Redirfdsy.disable_diag cplt_s_offs UINT32 Redir act.cplt_s_offs

[3117] 18.3. Use Cases

Desynchronizing Requests

[3118] 1. A part sends a request to the in terminal of DM_DSYR.

[3119] 2. Unless the disable_req property is TRUE, an EV_REQ_ENABLEevent is sent through the ctl terminal.

[3120] 3. The request is enqueued and the flow of control is returned tothe caller. The return status is ok_stat.

[3121] 4. Steps 1-3 may be repeated several times.

[3122] 5. DM_DSYR receives an EV_IDLE or EV_PULSE event from its ctlterminal.

[3123] 6. DM_DSYR dequeues one request and sends it out through the outterminal.

[3124] 7. When the request has completed, the same request with theCMEVT_A_COMPLETED attribute set is sent out through the back channel ofthe in terminal.

[3125] 8. Steps 5-7 are repeated many times.

[3126] 9. If the disable_ctl_req property is FALSE an EV_REQ_DISABLEevent is sent through the ctl terminal to stop the pulse generation(when the request queue becomes empty).

[3127] Notes 1. DM_DSYR assumes that requests sent through the interminal are not allocated on the caller's stack and their memory blockis valid at least until DM_DSYR sends the completion event.

DM_DWI—Desynchronizer with Idle Input

[3128]FIG. 85 illustrates the boundary of the inventive DM_DWI part.

[3129] DM_DWI de-couples the flow of control from the event flow, amechanism known as desynchronization. DM_DWI desynchronizes all eventsreceived on its in terminal. The input event is desynchronized only ifthe input event's attributes specify that it may be distributedasynchronously and it is self-contained. DM_DWI enqueues the event; thequeue keeps the events in the same order as they are received. AsEV_IDLE events are received on its idle input, DM_DWI dequeues all thepending events and sends them through the out terminal (one event isdequeued for each EV_IDLE event received). The size of the queue used byDM_DWI is dynamic and may be limited by a property called queue_sz.

[3130] DM_DWI issues EV_REQ_ENABLE and EV_REQ_DISABLE requests throughits idle terminal in order to control the idle generation. The issuingof these requests can be stopped through the property disable_idle_req.

[3131] 19. Boundary

[3132] 19.1. Terminals

[3133] Terminal “in” with direction “In” and contract I_DRAIN. Note:v-table, infinite cardinality, floating, synchronous. DM_DWIdesynchronizes the events received on this terminal.

[3134] Terminal “out” with direction “Out” and contract I_DRAIN. Note:v-table, cardinality 1, synchronous. DM_DWI sends all de-synchronizedqueued events out through this terminal (when it receives EV_IDLE fromidle). The outgoing events are in the same order as they were receivedfrom in.

[3135] Terminal “idle” with direction “Bi” and contract I_DRAIN. Note:v-table, cardinality 1, synchronous. EV_IDLE events are received throughthis terminal so DM_DWI can dequeue events and send them through the outterminal (one event is dequeued for each EV_IDLE event received). DM_DWIgenerates idle enable/disable requests through this terminal (unless thedisable_idle_req property is TRUE).

[3136] 19.2. Events and Notifications Incoming Event Bus Notes EV_XXXCMEVENT_(—) All incoming events received from in HDR/ are desynchronizedand sent out CMEvent through out.

[3137] Outgoing Event Bus Notes EV_XXX CMEVENT_(—) All incoming eventsreceived from in are HDR/ desynchronized and sent out through out.CMEvent The outgoing events are in the same order as they are receivedat in.

[3138] 19.3. Special Events, Frames, Commands or Verbs Special IncomingEvent Bus Notes EV_RESET CMEVENT_(—) This event is received on the idleHDR/ terminal. CMEvent In response, DM_DWI will flush its event queue.The events will be consumed by DM_DWI. EV_IDLE CMEVENT_(—) This event isreceived on the idle HDR/ terminal. CMEvent In response, DM_DWI willdequeue an event and send it through out. If there are no elements onthe queue, DM_DWI will return CMST_NO_ACTION even if disable_idle_reqproperty is set to TRUE.

[3139] Special Outgoing Event Bus Notes EV_REQ_(—) CMEVENT_(—) DM_DWIwill send this request out ENABLE HDR/ through idle when an event isreceived CMEvent on the in terminal and the queue was empty. DM_DWI willsend this event only if disable_idle_req property is FALSE. EV_REQ_(—)CMEVENT_(—) DM_DWI will send this request out DISABLE HDR/ through idleif the event queue is empty CMEvent (after receiving EV_IDLE anddequeueing the last event). DM_DWI will send this event only ifdisable_idle_req property is FALSE.

[3140] 19.4. Properties

[3141] Property “queue_sz” of type “UINT32”. Note: Default is 0. This isthe number of events that the queue can hold. If 0, the queue willextend itself when it gets full (the number of events the queue can holdis limited only by available memory).

[3142] Property “disable_idle_req” of type “UINT32”. Note: Default isFALSE. If FALSE, DM_DWI will send requests to enable/disable the idlegeneration when needed.

[3143] 20. Encapsulated Interactions

[3144] None.

[3145] 21. Specification

[3146] 22. Responsibilities

[3147] 1. Desynchronize all incoming events received through the interminal.

[3148] 2. When an EV_IDLE event is received from the idle terminal,dequeue and send an event out through the out terminal.

[3149] 3. Depending on the value of the disable_idle_req property,generate enable/disable requests through idle.

[3150] 23. Theory of Operation

[3151] 23.1. State Machine

[3152] None.

[3153] 23.2. Main Data Structures

[3154] DM_DWI uses a queue to store all desynchronized events.

[3155] 23.3. Mechanisms

Desynchronization of Incoming Events

[3156] DM_DWI starts by first examining the event attributes. If theevent is not distributed asynchronously or is not self-contained, DM_DWIwill not desynchronize the event and return CMST_REFUSE. If the event isnot self-owned, DM_DWI will make a copy and mark it as self-owned.

[3157] DM_DWI will then enqueue the event and return to the caller.DM_DWI will then request the idle generation (if the disable_idle_reqproperty is FALSE and the queue was empty). It does this by sending anEV_REQ_ENABLE event out through idle terminal.

[3158] For each EV_IDLE event received through its idle terminal, DM_DWIwill dequeue one event from the queue and send it out through out. Ifthe disable_idle_req property is FALSE and the queue is empty, DM_DWIwill request to disable the idle generation by sending an EV_REQ_DISABLEevent through idle.

[3159] 23.4. Use Cases

Desynchronizing Events

[3160] 10. The counter terminal of in sends an event to DM_DWI.

[3161] 11. Unless the disable_idle_req property is TRUE, anEV_REQ_ENABLE event will be sent out through the idle terminal.

[3162] 12. The event is enqueued and the flow of control is returned tothe caller.

[3163] 13. Steps 1 and 3 may be repeated several times.

[3164] 14. DM_DWI receives an EV_IDLE event from its idle terminal.

[3165] 15. DM_DWI dequeues one event and sends it out through the outterminal.

[3166] 16. Steps 5 and 6 are repeated.

[3167] 17. If the disable_idle_req property is FALSE an EV_REQ_DISABLEevent will be sent out the idle terminal (when the event queue becomesempty).

DM_DWI2—Desynchronizer with Idle Input

[3168]FIG. 86 illustrates the boundary of the inventive DM_DWI2 part.

[3169] DM_DWI2 de-couples the flow of control from the event flow, amechanism known as desynchronization. DM_DWI2 desynchronizes all eventsreceived on its in terminal. The input event is desynchronized only ifthe input event's attributes specify that it may be distributedasynchronously and it is self-contained.

[3170] DM_DWI2 enqueues the event; the queue keeps the events in thesame order as they are received. As EV_IDLE events are received on itsidle input, DM_DWI2 dequeues all the pending events and sends themthrough the out terminal (one event is dequeued for each EV_IDLE eventreceived). The size of the queue used by DM_DWI2 is dynamic and may belimited by a property called queue_sz.

[3171] DM_DWI2 issues EV_REQ_ENABLE and EV_REQ_DISABLE requests throughits idle terminal in order to control the idle generation.

[3172] The difference between DM_DWI2 and DM_DWI is that when DM_DWI2 isdisabled (i.e. it hasn't issued an EV_REQ_ENABLE event out idle) itreturns CMST_NO_ACTION for all events it receives on its idle terminaland does not emit EV_REQ_DISABLE event out idle terminal.

[3173] 24. Boundary

[3174] 24.1. Terminals

[3175] Terminal “in” with direction “In” and contract I_DRAIN. Note:v-table, infinite cardinality, floating, synchronous. DM_DWI2desynchronizes the events received on this terminal.

[3176] Terminal “out” with direction “Out” and contract I_DRAIN. Note:v-table, cardinality 1, synchronous. DM_DWI sends all de-synchronizedqueued events out through this terminal (when it receives EV_IDLE fromidle. The outgoing events are in the same order as they were receivedfrom in.

[3177] Terminal “idle” with direction “Bi” and contract I_DRAIN. Note:v-table, cardinality 1, synchronous. EV_IDLE events are received throughthis terminal so DM_DWI can dequeue events and send them through the outterminal (one event is dequeued for each EV_IDLE event received). DM_DWIgenerates idle enable/disable requests through this terminal

[3178] 24.2. Events and Notifications Incoming Event Bus Notes EV_XXXCMEVENT All incoming events received from in _HDR are desynchronized andsent out through RXW.

[3179] Outgoing Event Bus Notes EV_XXX CMEVENT All incoming eventsreceived from in _HDR are desynchronized and sent out through out. Theoutgoing events are in the same order as they are received at in.

[3180] 24.3. Special Events, Frames, Commands or Verbs Special IncomingEvent Bus Notes EV_RESET CMEVENT This event is received on the idleterminal. _HDR In response, DM_DWI2 will flush its event queue. Theevents will be consumed by DM_DWI2. EV_IDLE CMEVENT This event isreceived on the idle terminal. _HDR In response, DM_DWI2 will dequeue anevent and send it through out. If there are no elements on the queue,DM_DWI2 will return CMST_NO_ACTION

[3181] Special Outgoing Event Bus Notes EV_REQ_ENABLE CMEVENT DM_DWI2will send this request out through idle when _HDR an event is receivedon the in terminal and the queue was empty. EV_REQ_DISABLE CMEVENTDM_DWI2 will send this request out through idle if the _HDR event queueis empty (after receiving EV_IDLE and dequeueing the last event).

[3182] 24.4. Properties

[3183] Property “queue_sz” of type “UINT32”. Note: Default is 0. This isthe number of events that the queue can hold. If 0, the queue willextend itself when it gets full (the number of events the queue can holdis limited only by available memory).

[3184] 25. Internal Definition

[3185]FIG. 87 illustrates the internal structure of the inventiveDM_DWI2 part.

[3186] DM_DWI2 is a pure assembly and has no functionality of its own.Refer to the DM_DWI Data Sheet for a detailed functional overview of thedesynchronizer with idle input.

[3187] 26. Subordinate's Responsibilities

[3188] 26.1. DWI—Desynchronizer with Idle Input

[3189] 1. Implement an event queue that can be pumped with EV_IDLEevents.

[3190] 2. Clear the event queue on receipt of an EV_RESET event

[3191] 26.2. BSP—Bi-directional Splitter

[3192] 1. Provide plumbing to enable connection of a bidirectionalterminal to an unidirectional input or output.

[3193] 26.3. STP—Event Stopper

[3194] 1. Terminate the event flow by returning a specified status(e.g., CMST_OK).

[3195] 26.4. MUX—Event-Controlled Multiplexer

[3196] 1. Implements a switch between its out1 and out2 outputs that iscontrolled by event input on its ctl terminal.

[3197] 26.5. RPL—Event Replicator

[3198] 1. Duplicates events coming on in, send the duplicates to aux,and send the original event to out.

[3199] 27. Distribution of Properties Property Distr. Subordinatequeue_sz Redirected dwi.queue_sz

[3200] 28. Subordinate Parameterization Part Property Value dwidisable_idle_req FALSE rpl aux_first TRUE mux ev_out1 EV_REQ_DISABLEev_out2 EV_REQ_ENABLE spl ret_s CMST_NO_ACTION

DM_DWT, DM_DOT—Desynchronizers With Thread

[3201]FIG. 88 illustrates the boundary of the inventive DM_DWT ANDDM_DOT part.

[3202] DM_DWT desynchronizes and forwards events received on its ininput. The input event is desynchronized only if the input event'sattributes specify that it may be distributed asynchronously, otherwiseDM_DWT returns an error. Each instance of DM_DWT uses its own thread tode-queue the events queued through in and send them to out.

[3203] Before an input event is queued, DM_DWT checks the self-ownedattribute of the event (CMEVT_A_SELF_OWNED). If it is set, the event isqueued as-is, otherwise a copy of the event is queued. In any case theoutput is called with the self-owned attribute cleared¹. DM_DWT freesthe event memory after the call to out returns.

[3204] DM_DOT has the same functionality, but it provides a singlebi-directional terminal to receive the input events and send thede-synchronized events. It can be used in cases when a part needs topostpone the processing of an event and/or request to be called back ina different thread of execution in order to perform operations that itcannot do in its current execution context.

[3205] Note The desynchronized event may be distributed in a threaddifferent than the one that posted it. This may impose additionallimitations if thread-local storage is used.

[3206] 29. Boundary

[3207] 29.1. Terminals (DM_DWT)

[3208] Terminal “in” with direction “In” and contract I_DRAIN. Note:v-table, infinite cardinality, synchronous This terminal receives allthe incoming events for DM_DWT. Events that require synchronousdistribution are rejected with CMST_REFUSE status. Such events are thosethat have only the CMEVT_A_SYNC attribute set. In general, all theevents to be desynchronized by DM_DWT should have both the CMEVT_A_SYNCand the CMEVT_A_ASYNC attribute set.

[3209] Terminal “out” with direction “Out” and contract I_DRAIN. Note:v-table, cardinality 1, synchronous DM_DSY sends all de-synchronizedevents out through this terminal.

[3210] This output is called in a dedicated worker thread created byDM_DWT (a separate thread is created by each instance of DM_DWT).

[3211] 29.2. Terminals (DM_DOT)

[3212] Terminal “dsy” with direction “I/O” and contract I_DRAIN. Note:v-table, cardinality 1, synchronous This terminal receives all theincoming events for DM_DOT. Events that require synchronous distributionare rejected with CMST_REFUSE status. Such events are those that haveonly the CMEVT_A_SYNC attribute set. In general, all the events to bedesynchronized by DM_DWT should have both the CMEVT_A_SYNC and theCMEVT_A_ASYNC attribute set. The de-synchronized events are sent outthrough the same terminal. The output is called in a dedicated workerthread created by DM_DOT (a separate thread is created by each instanceof DM_DOT).

[3213] 29.3. Events and Notifications Incoming Event Bus Notes EV_XXXCMEVENT DM_DWT: All incoming events on in are de- _HDR synchronized andsent out through out. /CMEvent DM_DOT: All incoming events on dsy arede- synchronized and sent back through dsy.

[3214] 29.4. Outgoing Event Bus Notes EV_XXX CMEVENT All incoming eventson in(dsy) are de- _HDR synchronized and sent out through out(dsy)./CMEvent

[3215] 29.5. Special Events, Frames, Commands or Verbs

[3216] None.

[3217] 29.6. Properties

[3218] Property “queue_sz” of type “UINT32”. Note: This is the number ofevents that the event queue can hold. If 0, the queue will extend itselfwhen it gets full (the number of events the queue can hold is limitedonly by available memory). This property is redirected to the ESTsubordinate. Default is 0.

[3219] Property “thread_priority” of type “UINT32”. Note: Specifies thepriority of the worker thread. The values for this property depend onthe environment. It is used directly to call the environment specificfunction that sets the thread priority (SetThreadPriority in Win32,KeSetPriorityThread in WDM, etc.). This property is redirected to theEST subordinate.

[3220] 30. Encapsulated Interactions

[3221] The DM_EST part used in the DM_DWT and DM_DOT assemblies uses thefollowing operating system services:

[3222] Thread functions

[3223] Synchronization functions

[3224] Note that these functions are different in each operatingenvironment. For details, please refer to the DM_EST data sheet.

[3225] 31. Specification

[3226]FIG. 89 illustrates the internal structure of the inventive DM_DWTpart.

[3227]FIG. 90 illustrates the internal structure of the inventive DM_DOTpart.

[3228] 32. Responsibilities

[3229] 1. Desynchronize all incoming events received from in/dsy andsend them out through out/dsy.

[3230] 2. Use a dedicated worker thread to call the out/dsy terminal.

[3231] 33. Theory of Operation

[3232] DM_DWT and DM_DOT are assemblies built entirely of DriverMagicparts.

[3233] For simplicity, the description below refers to DM_DWT only. Thesame description is valid for DM_DOT, except that DM_DWT has separateinput and output while DM_DOT has a single bidirectional terminal forboth input and output (see the diagrams above).

[3234] An event that enters DM_DWT is enqueued by DM_DWI and controlreturns to the caller immediately with CMST_OK (if DM_DWI fails toenqueue the event—i.e., the queue is full or the event does not qualifyas de-synchronizable, an error status is returned).

[3235] If this is the first event enqueued, DM_DWI sends an enablerequest to its idle terminal. This request is translated by DM_IES to an“arm” operation sent to DM_EST, which in turn unblocks the worker threadcreated by DM_EST. When the worker thread receives control, DM_EST calls“fire” on its output continuously, until disabled. The “fire” operationsare translated by DM_IES into EV_IDLE events used by DM_DWI to de-queueevents from its queue and send them to out.

[3236] When the queue becomes empty, DM_DWI sends a disable request(translated to “disarm” on DM_EST), which causes the worker thread to beblocked until a new event is enqueued.

[3237] 34. Subordinate Parameterization Subordinate Property ValueDM_EST force_defaults TRUE auto_arm FALSE continuous TRUE

[3238] 34.1. Use Cases

De-synchronizing Events with DM_DWT

[3239]FIG. 91 illustrates an advantageous use of the inventive DM_DWTpart.

[3240]FIG. 92 illustrates an advantageous use of the inventive DM_DWTpart.

[3241] If one or more event sources are connected to a single eventrecipient and all the event sources produce only de-synchronizable²events, DM_DWT may be placed in front of the recipient if a directconnection is undesirable for any of the following reasons (or othersimilar considerations):

[3242] The event source(s) do not execute in a normal thread context,while the recipient requires normal thread context to run.

[3243] The event source(s) may not be blocked for any reason, while therecipient calls (or is expected to call) system functions that can blockthe thread and/or its outputs when it receives an event.

[3244] If there is a direct or indirect loopback path from the eventrecipient to the event source—to avoid re-entering the source andcausing an infinite loop or recursion that may oveflow the call stack.

[3245] a) the event data buffer is not in any way bound to the executioncontext of the caller (e.g., is not allocated on the caller's stack anddoes not use or refer to thread-specific data) or it may be safelycopied (i.e., has no references to volatile data, like automatic orheap-allocated buffers that can become unavailable when the event isde-queued);

[3246] b) the event source does not need to receive a return status ordata placed in the event data buffer from the processing of the event;

[3247] c) the event source can continue execution whether or not theevent was actually delivered.

[3248] Note that since an instance of DM_DWT uses a single thread, thede-synchronized events are also serialized, i.e., the part connected toDM_DWT's output will receive them in sequence and will never bere-entered from this connection with a new event until it has returnedfrom the previous one. If serialization of events from multiple sourcesis undesirable, a separate instance of DM_DWT may be used tode-synchronize events from each of the sources.

Serializing and/or Postponing Processing of Events Generated Inside aPart with DM_DOT

[3249]FIG. 93 illustrates an advantageous use of the inventive DM_DOTpart.

[3250] Some parts interact with sources of asynchronous events(“Asynchronous event” here does not necessarily refer to a ClassMagicevent, but to any type of entry into the part that is asynchronous,e.g., a callback from the operating system or an embedded interaction),which may come in an execution context that is restricted in some way,e.g.:

[3251] the part's guard cannot be acquired;

[3252] access to some system services is restricted;

[3253] the event requires lengthy processing and the current thread ofexecution may not be blocked or delayed.

[3254] the execution context may not be suitable for calling the part'soutputs, because parts connected to these outputs cannot enter theirguard and/or cannot call system APIs at that time.

[3255] In such cases the part needs to defer part or all processing ofasynchronous events and request to be re-entered in a normal threadcontext. To do this it should have a bidirectional I_DRAIN terminal(dsy—see diagram) connected to an instance of DM_DOT. When it needs topostpone an event, it fills in a ClassMagic event structure with all theinformation required to process the event later and sends it throughdsy. DM_DOT will later call it back through the same terminal with theposted event structure—in the context of its working thread.

DM_DWP, DM_DOP—Desynchronizers With DriverMagic Pump

[3256]FIG. 94 illustrates the boundary of the inventive DM_DWP andDM_DOP parts.

[3257] DM_DWP desynchronizes and forwards operation requests received onits in input. DM_DWP uses the DriverMagic pump to desynchronize theoperations received through in and send them to out. The operationrequests are dispatched in the execution context of the DriverMagic pumpthread.

[3258] DM_DOP has the same functionality, but it provides a singlebi-directional terminal to receive the input requests and send thede-synchronized requests. It can be used in cases when a part needs topostpone the processing of an event and/or request to be called back ina different thread of execution in order to perform operations that itcannot do in its current execution context.

[3259] Note The desynchronized operation request may be distributed in athread different than the one that posted it. This may impose additionallimitations if thread-local storage is used.

[3260] 35. Boundary

[3261] 35.1. Terminals (DM_DWP)

[3262] Terminal “in” with direction “In” and contract I_POLY. Note:v-table, infinite cardinality, synchronous This terminal receives allthe incoming operation requests for DM_DWP.

[3263] Terminal “out” with direction “Out” and contract I_POLY. Note:v-table, cardinality 1, synchronous DM_DWP sends all de-synchronizedoperation requests out through this terminal. This output is called inthe thread context of the DriverMagic pump.

[3264] 35.2. Terminals (DM_DOP)

[3265] Terminal “dsy” with direction “Plug” and contract I_POLY. Note:v-table, cardinality 1, synchronous This terminal receives all theincoming operation requests for DM_DOP. This output is called in thethread context of the DriverMagic pump.

[3266] 35.3. Events and Notifications

[3267] None.

[3268] 35.4. Special Events, Frames, Commands or Verbs

[3269] None.

[3270] 35.5. Properties

[3271] Property “queue_sz” of type “UINT32”. Note: This is the number ofoperation requests that the operation queue can hold. If 0, the queuewill extend itself when it gets full (the number of operations the queuecan hold is limited only by available memory). Default is 0.

[3272] Property “ok_stat” of type “UINT32”. Note: This specifies thestatus that DM_DWP/DM_DOP returns on calls through in if the operationrequest was successfully enqueued. This status is also used to determineif operation requests passed through out succeeded. Default is CMST_OK.

[3273] Property “disable_diag” of type “UINT32”. Note: Boolean. Thisdetermines whether DM_DWP/DM_DOP prints debug output indicating that acall through out failed. A call through out fails if the return statusis not equal to ok_stat. This property affects only the checked build ofDM_DWP/DM_DOP. Default is FALSE.

[3274] 36. Encapsulated Interactions

[3275] DM_DWP and DM_DOP use the DriverMagic pump in order todesynchronize the operation requests.

[3276] 37. Specification

[3277]FIG. 95 illustrates the internal structure of the inventive DM_DWPpart.

[3278]FIG. 96 illustrates the internal structure of the inventive DM_DOPpart.

[3279] 38. Responsibilities

[3280] 1. Desynchronize all incoming operation requests received fromin/dsy and send them out through out/dsy.

[3281] 39. Theory of Operation

[3282] DM_DWP and DM_DOP are assemblies built entirely of DriverMagicparts.

[3283] For simplicity, the description below refers to DM_DWP only. Thesame description is valid for DM_DOP, except that DM_DWP has separateinput and output while DM_DOP has a single bidirectional terminal forboth input and output (see the diagrams above).

[3284] An operation request that enters DM_DWP is enqueued by DM_FDSYand control returns to the caller immediately with CMST_OK (if DM_FDSYfails to enqueue the request—i.e., the queue is full; an error status isreturned).

[3285] If this is the first request enqueued, DM_FDSY sends an enablerequest to its ctl terminal. This request is translated by DM_IES to an“arm” operation sent to DM_ESP, which in turn posts a message to itself.When the message is dispatched by the DriverMagic pump, DM_ESP calls“fire” on its output continuously, until disabled. The “fire” operationsare translated by DM_IES into EV_IDLE events used by DM_FDSY to de-queuerequests from its queue and send them to out.

[3286] When the queue becomes empty, DM_FDSY sends a disable request(translated to “disarm” on DM_ESP), which causes DM_ESP to no longerpost messages to itself until a new operation request is enqueued.

[3287] 40. Distribution of Properties Property Distr. Subordinatequeue_sz Redirected fdsy.queue_sz ok_stat Redirected fdsy.ok_statdisable_diag Redirected fdsy.disable_diag

[3288] 41. Subordinate Parameterization Subordinate Property ValueDM_ESP force_defaults TRUE auto_arm FALSE continuous TRUE DM_FDSYdisable_ctl_req FALSE

DM_DWW, DM_DOW—Desynchronizers With Window

[3289]FIG. 97 illustrates the boundary of the inventive DM_DWW andDM_DOW parts.

[3290] DM_DWW desynchronizes and forwards events received on its ininput. The input event is desynchronized only if the input event'sattributes specify that it may be distributed asynchronously, otherwiseDM_DWW returns an error. Each instance of DM_DWW uses its own window tode-queue the events queued through in and send them to out. The eventsare dispatched in the same thread in which DM_DWW was created.

[3291] Before an input event is queued, DM_DWW checks the self-ownedattribute of the event (CMEVT_A_SELF_OWNED). If it is set, the event isqueued as-is, otherwise a copy of the event is queued. In any case theoutput is called with the self-owned attribute cleared¹. DM_DWW freesthe event memory after the call to out returns.

[3292] DM_DOW has the same functionality, but it provides a singlebi-directional terminal to receive the input events and send thede-synchronized events. It can be used in cases when a part needs topostpone the processing of an event and/or request to be called back ina different thread of execution in order to perform operations that itcannot do in its current execution context.

[3293] DM_DWW and DM_DOW are only available in the Win32 environment.

[3294] Note The desynchronized event may be distributed in a threaddifferent than the one that posted it. This may impose additionallimitations if thread-local storage is used.

[3295] 42. Boundary

[3296] 42.1. Terminals (DM_DWW)

[3297] Terminal “in” with direction “In” and contract I_DRAIN. Note:v-table, infinite cardinality, synchronous This terminal receives allthe incoming events for DM_DWW. Events that require synchronousdistribution are rejected with CMST_REFUSE status. Such events are thosethat have only the CMEVT_A_SYNC attribute set. In general, all theevents to be desynchronized by DM_DWW should have both the CMEVT_A_SYNCand the CMEVT_A_ASYNC attribute set.

[3298] Terminal “out” with direction “Out” and contract I_DRAIN. Note:v-table, cardinality 1, synchronous DM_DWW sends all de-synchronizedevents out through this terminal. This output is called in the samethread context of its window, which is the same thread in which DM_DWWwas created in. (a separate window is created by each instance ofDM_DWW).

[3299] 42.2. Terminals (DM_DOW)

[3300] Terminal “dsy” with direction “I/O” and contract I_DRAIN. Note:v-table, cardinality 1, synchronous This terminal receives all theincoming events for DM_DOW. Events that require synchronous distributionare rejected with CMST_REFUSE status. Such events are those that haveonly the CMEVT_A_SYNC attribute set. In general, all the events to bedesynchronized by DM_DWW should have both the CMEVT_A_SYNC and theCMEVT_A_ASYNC attribute set. The de-synchronized events are sent outthrough the same terminal. The output is called in the same threadcontext of its window, which is the same thread in which DM_DWW wascreated in. (a separate widnow is created by each instance of DM_DOW).

[3301] 42.3. Events and Notifications Incoming Event Bus Notes EV_XXXCMEVENT DM_DWW: All incoming events on in are de- _HDR synchronized andsent out through out. /CMEvent DM_DOW: All incoming events on dsy aredesynchronized and sent back through dsy.

[3302] 42.4. Outgoing Event Bus Notes EV_XXX CMEVENT All incoming eventson in(dsy) are _HDR de-synchronized and sent out through out(dsy)./CMEvent

[3303] 42.5. Special Events, Frames, Commands or Verbs

[3304] None.

[3305] 42.6. Properties

[3306] Property “thread_priority” of type “INT32”. Note: Specifies thepriority of the worker thread. The values for this property depend onthe environment. It is used directly to call the environment specificfunction that sets the thread priority (SetThreadPriority lo in Win32,KeSetPriorityThread in WDM, etc.).

[3307] 43. Encapsulated Interactions

[3308] The DM_ESW part used in the DM_DWW and DM_DOW assemblies uses thefollowing Win32 APIs to control its event window and timers:

[3309] RegisterClass( )

[3310] DeregisterClass( )

[3311] CreateWindow( )

[3312] DestroyWindow( )

[3313] SetTimer( )

[3314] KillTimer( )

[3315] PostMessage( )

[3316] 44. Specification

[3317]FIG. 98 illustrates the internal structure of the inventive DM_DWWpart.

[3318]FIG. 99 illustrates the internal structure of the inventive DM_DOWpart.

[3319] 45. Responsibilities

[3320] 1. Desynchronize all incoming events received from in/dsy andsend them out through out/dsy in the same thread context in which it wascreated.

[3321] 46. Theory of Operation

[3322] DM_DWW and DM_DOW are assemblies built entirely of DriverMagicparts.

[3323] For simplicity, the description below refers to DM_DWW only. Thesame description is valid for DM_DOW, except that DM_DWW has separateinput and output while DM_DOW has a single bi-directional terminal forboth input and output (see the diagrams above).

[3324] An event that enters DM_DWW is enqueued by DM_DWI and controlreturns to the caller immediately with CMST_OK (if DM_DWI fails toenqueue the event—i.e., the queue is full or the event does not qualifyas de-synchronizable, an error status is returned).

[3325] If this is the first event enqueued, DM_DWI sends an enablerequest to its idle terminal. This request is translated by DM_IES to an“arm” operation sent to DM_ESW, which in turn posts a message to itswindow. When the window receives the message, DM_ESW calls “fire” on itsoutput continuously, until disabled. The “fire” operations aretranslated by DM_IES into EV_IDLE events used by DM_DWI to de-queueevents from its queue and send them to out.

[3326] When the queue becomes empty, DM_DWI sends a disable request(translated to “disarm” on DM_ESW), which causes DM_ESW to no longerpost messages to its window until a new event is enqueued.

[3327] 47. Subordinate Parameterization Subordinate Property ValueDM_ESW force_defaults TRUE auto_arm FALSE continuous TRUE

[3328] Notes Some parts interact with sources of asynchronous events(embedded interactions), which may come in an execution context that isrestricted in some way, e.g.:

[3329] the part's guard cannot be acquired;

[3330] access to some system services is restricted;

[3331] the event requires lengthy processing and the current thread ofexecution may not be blocked or delayed.

[3332] the execution context may not be suitable for calling the part'soutputs, because parts connected to these outputs cannot enter theirguard and/or cannot call system APIs at that time.

[3333] All outgoing events must be sent in the same thread that theDM_DOW was created.

[3334]  In such cases the part needs to defer part or all processing ofasynchronous events and request to be reentered in a normal threadcontext. To do this it should have a bi-directional I_DRAIN terminal(dsy—see diagram) connected to an instance of DM_DOW. When it needs topostpone an event, it fills in a ClassMagic event structure with all theinformation required to process the event later and sends it throughdsy. DM_DOW will later call it back through the same terminal with theposted event structure—in the thread context in which it was created.

[3335] 1. In order for DM_DOW and DM_DWW to work correctly, theapplication that contains the parts must provide a message dispatch loopas defined by Windows. This allows the messages for an application to bedispatched to the aprpropriate window. Please see the Win32documentation for more information.

[3336] 2. As Win32 requires that windows be destroyed in the same threadin which they are created, DM_DOW and DM_DWW also must be destroyed inthe same thread in which they were created. Failure to do so willtypically fail to destroy the window.

DM_RDWT—Request Desynchronizer With Thread

[3337]FIG. 100 illustrates the boundary of the inventive DM_RDWT part.

[3338] DM_RDWT desynchronizes and forwards requests received on its ininput. The input request is assumed not to be allocated on the caller'sstack. Each instance of DM_RDWT uses its own thread to de-queue therequests queued through in and sends them to out. The desynchronizedrequests sent through out are in the context of DM_RDWT's worker thread.

[3339] If the incoming request does not have the CMEVT_A_ASYNC_CPLTattribute set DM_RDWT fails with CMST_REFUSE. For each request, there isgarenteed to be a completion event sent back through in.

[3340] All events received on out are forwarded through in withoutmodification (synchronously).

[3341] 48. Boundary

[3342] 48.1. Terminals

[3343] Terminal “in” with direction “Plug” and contract I_DRAIN. Note:v-table, cardinality 1, synchronous This terminal receives all theincoming requests for DM_RDWT. Completion events for asynchronouslycompleted requests are received from out and are forwarded out throughin.

[3344] Terminal “out” with direction “Plug” and contract I_DRAIN. Note:v-table, cardinality 1, synchronous DM_DSY sends all de-synchronizedrequests out through this terminal. This output is called in a dedicatedworker thread created by DM_RDWT (a separate thread is created by eachinstance of DM_RDWT). Completion events for asynchronously completedrequests are received by this terminal and are forwarded out through in.

[3345] 48.2. Events and Notifications Incoming Event Bus Notes EV_XXXCMEVENT All incoming requests on in are _HDR de-synchronized and sentout through out. /CMEvent

[3346] 48.3. Outgoing Event Bus Notes EV_XXX CMEVENT All incoming eventson in are _HDR de-synchronized and sent out through out. /CMEvent

[3347] 48.4. Special Events, Frames, Commands or Verbs

[3348] None.

[3349] 48.5. Properties

[3350] Property “thread priority” of type “UINT32”. Note: Specifies thepriority of the worker thread. The values for this property depend onthe environment. It is used directly to call the environment specificfunction that sets the thread priority (SetThreadPriority in Win32,KeSetPriorityThread in WDM, etc.). This property is redirected to theEST subordinate.

[3351] Property “queue_sz” of type “UINT32”. Note: This is the number ofrequests that the request queue can hold. If 0, the queue will extenditself when it gets full (the number of events the queue can hold islimited only by available memory). This property is redirected to theDSYR subordinate. Default is 0.

[3352] Property “disable_diag” of type “UINT32”. Note: Boolean. Thisdetermines whether DM_RDWT prints debug output indicating that a callthrough out failed. A call through out fails if the return status is notequal to ok_stat. This property affects only the checked build ofDM_RDWT. This property is redirected to the DSYR subordinate. Default isFALSE.

[3353] Property “cplt_s_offs” of type “UINT32”. Note: Offset in bytes ofthe completion status in the request bus. This property is redirected tothe DSYR subordinate. Mandatory.

[3354] 49. Encapsulated Interactions

[3355] The DM_EST part used in the DM_RDWT assembly uses the followingoperating system services:

[3356] Thread functions

[3357] Synchronization functions

[3358] Note that these functions are different in each operatingenvironment. For details, please refer to the DM_EST data sheet.

[3359] 50. Specification

[3360]FIG. 101 illustrates the internal structure of the inventiveDM_RDWT part.

[3361] 51. Responsibilities

[3362] 1. Desynchronize all incoming requests received from in and sendthem through out.

[3363] 2. Use a dedicated worker thread to call the out terminal.

[3364] 52. Theory of Operation

[3365] DM_RDWT is an assembly built entirely of DriverMagic parts.

[3366] A request that enters DM_RDWT is enqueued by DM_DSYR and controlreturns to the caller immediately with CMST_OK (if DM_DSYR fails toenqueue the request—i.e., the queue is full an error status isreturned).

[3367] If this is the first request enqueued, DM_DSYR sends an enablerequest to its ctl terminal. This request is translated by DM_IES to an“arm” operation sent to DM_EST, which in turn starts issuing “fire”calls in its own thread. The “fire” operations are translated by DM_IESinto EV_IDLE events used by DM_DSYR to de-queue requests from its queueand send them to out.

[3368] When the queue becomes empty, DM_DSYR sends a disable request(translated to “disarm” on DM_EST), which causes the DM_EST to stopfiring until a new request is enqueued.

[3369] 53. Subordinate's Responsibilities

[3370] 53.1. DM_DSYR—Desynchronizer for Requests

[3371] Desychronize incoming requests on in and send them through out.

[3372] 53.2. DM_IES—Idle to Event Source Adapter

[3373] Convert EV_REQ_ENABLE and EV_REQ_DISABLE requests on the idleterminal into arm and disarm operations on the evs terminalrespectively.

[3374] In response to fire operation calls through the evs terminal,generate EV_IDLE requests through idle until CMST_NO_ACTION is returnedfrom the idle processing or an EV_REQ_DISABLE request is received.

[3375] 53.3. DM_EST—Event Source by Thread

[3376] Issue “fire” calls within the context of its own thread.

[3377] 54. Dominant's Responsibilities

[3378] 54.1. Hard Parameterization of Subordinates Subordinate PropertyValue DM_DSYR disable_ctl_req FALSE DM_EST force_defaults TRUE auto_armFALSE continuous TRUE

[3379] 54.2. Distribution of Properties to the Subordinates PropertyName Type Dist To thread_priority UINT3 Redir est.thread_priority 2queue_sz UINT3 Redir dsyr.queue_sz 2 disable_diag UINT3 Redirdsyr.disable_diag 2 cplt_s_offs UINT3 Redir dsyr.cplt_s_offs 2

[3380] 55. Notes

[3381] The desynchronized requests are distributed in a thread differentthan the one that posted it. This may impose additional limitations ifthread-local storage is used.

Resynchronizers DM_RSY, DM_RSB—Re-synchronizers

[3382]FIG. 102 illustrates the boundary of the inventive DM_RSB part.

[3383]FIG. 103 illustrates the boundary of the inventive DM_RSY part.

[3384] 1. Overview

[3385] DM_RSY is an adapter that converts a Request Event that isexpected to complete synchronously into a Request Event that maycomplete either synchronously or asynchronously.

[3386] By doing this, DM_RSY provides the part connected to its outterminal with the option to either complete the request immediately orreturn CMST_PENDING and delay the actual completion of the request for afuture time.

[3387] At the same time DM_RSY ensures that the part connected to the interminal will receive control back (DM_RSY will return from raiseoperation) only after the processing of the request has actually beencompleted.

[3388] DM_RSY is parameterized with the event ID of the Request Event,which needs to be adapted for asynchronous processing. Additionalproperties control details of how the adapting procedure is performed.

[3389] DM_RSB has the same functionality as DM_RSY, but allowsbi-directional connections to its in terminal. The back channel of thein terminal is used to transparently forward all events received on theback channel of the out terminal, allowing DM_RSB to be inserted inbidirectional connections.

[3390] 2. Details

[3391] DM_RSY uses a specialized protocol to accomplish the process ofresynchronization. DM_RSY sets an attribute (the value of this attributeis a property) on the incoming event, indicating that the request can becompleted asynchronously, and forwards the event to its out terminal.

[3392] The part connected to that terminal may complete the processingimmediately (synchronously) or may decide to delay the processing andreturn CMST_PENDING.

[3393] If the request was completed synchronously, DM_RSY returnsimmediately to the originator. If the processing was delayed(CMST_PENDING was returned) however, DM_RSY will block the originator ofthe event and wait for an event to come from the back channel of the outterminal (the event ID is a property) indicating that the request hasbeen completed. After DM_RSY receives such event, it will return to theRequest Event originator (restoring the original attributes).

[3394] 3. Boundary

[3395] 3.1. Terminals (DM_RSY)

[3396] Terminal “in” with direction “Input” and contract I_DRAIN. Note:v-table, infinite cardinality, synchronous, activetime The req_ev_idevent is expected to be received on this terminal. If req_ev_id isEV_NULL, any event may be received on this terminal.

[3397] Terminal “out” with direction “Bidir (plug)” and contractI_DRAIN. Note: v-table, cardinality 1, synchronous, unguarded Thecplt_ev_id event is expected to be received on this terminal.

[3398] 3.2. Terminals (DM_RSB)

[3399] Terminal “in” with direction “Bidir (plug)” and contract I_DRAIN.Note: v-table, cardinality 1, synchronous The req_ev_id event isexpected to be received on this terminal. If req_ev_id is EV_NULL, anyevent may be received on this terminal.

[3400] Terminal “out” with direction “Bidir (plug)” and contractI_DRAIN. Note: v-table, cardinality 1, synchronous, unguarded Thecplt_ev_id event is expected to be received on this terminal.

[3401] 3.3. Events and Notifications

[3402] The re-synchronizers recognize two specific events: req_ev_id andcplt_ev_id. The event IDs for these two events are specified asproperties and are described in the tables below: Incoming Event BusNotes req_ev_id CMEVENT_ The event that requests a synchronous orasynchronous HDR operation. or extended This event ID is specified as aproperty on the re- synchronizers. This event is expected to be receivedon the in terminal. If req_ev_id is EV_NULL, any event may be re-synchronized. This event may be the same as cplt_ev_id. cplt_ev_idCMEVENT_ The event that signifies that an asynchronous HDR operation,requested by a preceding req_ev_id, has or extended completed. Thisevent ID is specified as a property on the re- synchronizers. This eventis expected to be received on the out terminal. This event may be thesame as req_ev_id. all others CMEVENT_ All incoming events received fromthe in terminal are HDR forwarded through out. or extended DM_RSB:Unrecognized events received from the out terminal are forwarded throughin if the re-synchronizer is not expecting to receive a completionnotification. Otherwise, the event is refused. DM_RSY: Unrecognizedevents received from the out terminal are not processed by DM_RSY andCMST_NOT_CONNECTED is returned.

[3403] 3.4.

[3404] 3.5. Outgoing Event Bus Notes req_ev_id CMEVENT_ The event thatrequests a synchronous or asynchronous HDR operation. or extended Thisevent ID is specified as a property on the re- synchronizers. Thisevent, when received on the in terminal, is passed through the outterminal. all others CMEVENT_ All incoming events received from the interminal are HDR forwarded through out. or extended

[3405] 3.6. Special Events, Frames, Commands or Verbs

[3406] None.

[3407] 3.7. Properties

[3408] Property “req_ev_id” of type “UINT32”. Note: This is the ID ofthe event that requests the operation that needs to be completedasynchronously. If req_ev_id is EV_NULL, any event may bere-synchronized. This event is expected to be received on the interminal. This event may be the same as cplt_ev_id. Default is EV_NULL.

[3409] Property “cplt_ev_id” of type “UINT32”. Note: This is the ID ofthe event that signifies the completion of the asynchronous operation.This event is expected to be received on the out terminal. If cplt_ev_idis EV_NULL, the completion event must be the same as req_ev_id,otherwise it may be a different event. Default is EV_NULL.

[3410] Property “async_cplt_attr” of type “UINT32”. Note: This is theevent-specific attribute to be set on the req_ev_id event in order tosignify that the requested operation can be completed asynchronously.The attribute value may be 0. Default is CMEVT_A_ASYNC_CPLT.

[3411] Property “cplt_attr” of type “UINT32”. Note: This is theevent-specific attribute to be set on the cplt_ev_id event in order tosignify that the asynchronous operation has completed. This attribute isused only if req_ev_id is the same as cplt_ev_id. The attribute valuemay be 0. Default is CMEVT_A_COMPLETED.

[3412] Property “copy_cplt_data” of type “BOOL”. Note: If TRUE, there-synchronizer copies the completion data from the completion event busto the event bus of the originator of the request. Default is FALSE.

[3413] Property “extract_cplt_s” of type “BOOL”. Note: If TRUE, there-synchronizer extracts the completion status from the completion eventbus and return it to the originator of the request. Default is FALSE.

[3414] Property “cplt_s_offset” of type “UINT32”. Note: This is theoffset from the beginning of the completion event bus (in bytes), wherethe completion status is stored. This property is ignored ifextract_cplt_s is FALSE. Default is 0×0C.

[3415] 4. Encapsulated Interactions

[3416] DM_RSY uses the synchronization services (Events) of theoperating system to block the thread that requests the operation whichis desynchronized.

[3417] 5. Dependencies

[3418] DM_RSY requires DM_BSP and DM_RSB to be available.

[3419] 6. Specification

[3420] 7. Responsibilities

[3421] 1. Pass all events received from the in terminal through the outterminal.

[3422] 2. DM_RSB: Pass all unrecognized events received from the outterminal through the in terminal (only if the re-synchronizer is notexpecting to receive a completion notification; otherwise the event isrefused).

[3423] 3. DM_RSY: Ignore unrecognized events received from the outterminal.

[3424] 4. If an req_ev_id event is received on the in terminal, forwardthe event through out and block the caller (if needed) until thecplt_ev_id event is received on the out terminal. If an req_ev_id isEV_NULL, allow any event to be re-synchronized.

[3425] 5. When an asynchronous operation completes, return the resultsand control back to the caller.

[3426] 8. Theory of Operation

[3427]FIG. 104 illustrates the internal structure of the inventiveDM_RSY part.

[3428] 8.1. Interior

[3429] DM_RSB is a coded part.

[3430] DM_RSY is a static assembly.

[3431] 8.2. Mechanisms

Handling Operation Requests from the In Terminal

[3432] When the re-synchronizer receives an req_ev_id event (or anyevent if req_ev_id is EV_NULL) from the in terminal, it sets theasynchronous completion attribute (specified by async_cplt_attr) andforwards the event through the out terminal.

[3433] If any status other than CMST_OK or CMST_PENDING is returned fromthe event processing, this is considered an error and the status isreturned to the caller.

[3434] If the return status is CMST_OK (or any status other thanCMST_PENDING) the operation completed synchronously. In this case, there-synchronizer returns control back to the caller and does nothingelse.

[3435] If the return status is CMST_PENDING, the operation will completeasynchronously. The re-synchronizer blocks the caller (using an eventsynchronization object) until it receives an cplt_ev_id event on its outterminal. When an cplt_ev_id event is received, the event object issignaled and control is returned back to the caller.

[3436] In all cases, before the control is returned back to the caller,the event-specific attributes (possibly modified by the re-synchronizer)are restored to their original values.

[3437] The re-synchronizers pass all other events from the in terminalthrough the out terminal without modification.

Notification of Asynchronous Operation Completion

[3438] The re-synchronizer blocks the caller (as described in themechanism above) until it receives an cplt_ev_id event on its outterminal. This event indicates that the asynchronous operation iscomplete.

[3439] If the completion event (cplt_ev_id) is the same as the operationrequest event (req_ev_id), the re-synchronizer expects that thecompletion attribute (cplt_attr) is set. If not, the re-synchronizerreturns CMST_REFUSE.

[3440] When the asynchronous operation has completed, the caller isunblocked by signaling the event object. The re-synchronizer uses thevalues of the properties copy_cplt_data and extract_cplt_s to determineif it should copy the completion event bus and/or return the completionstatus to the caller. The caller receives the results of theasynchronous operation and continues execution as if the requestedoperation had completed synchronously.

[3441] If an unrecognized event is received on the out terminal and there-synchronizer is not expecting to receive a completion notification,it will pass the event through the in terminal. If a completion event isexpected, the event is refused.

Extraction of the Completion Status

[3442] When the asynchronous operation has completed, there-synchronizer uses the value of the extract cplt_s_property todetermine whether the completion status is returned to the caller.

[3443] If extract_cplt_s is TRUE, the re-synchronizer uses the value ofcplt_s_offset to determine where the completion status is stored in thecompletion event bus. The status is extracted and returned to thecaller.

[3444] If extract_cplt_s is FALSE, the re-synchronizer returns CMST_OKto the caller.

[3445] 8.3. Use Cases

[3446]FIG. 105 illustrates an advantageous use of the inventive DM_RSYpart.

[3447]FIG. 106 illustrates an advantageous use of the inventive DM_RSBpart.

Requested Operation Completes Synchronously

[3448] 1. The structures in FIGS. 3 and 4 are created, connected, andactivated.

[3449] 2. At some point, the re-synchronizer receives an req_ev_id eventon its in terminal.

[3450] 3. The re-synchronizer sets the asynchronous attribute(async_cplt_attr) in the event bus to indicate that the operation cancomplete asynchronously if needed.

[3451] 4. The event is passed through the out terminal.

[3452] 5. The part connected to the re-synchronizer's out terminalreceives the event and completes the operation synchronously. Control isreturned back to the re-synchronizer.

[3453] 6. The re-synchronizer returns control back to the caller.

[3454] 7. Steps 2-6 may be executed many times.

[3455] 8. The re-synchronizer is deactivated, disconnected, anddestroyed.

Requested Operation Completes Asynchronously

[3456] 1. The structures in FIGS. 3 and 4 are created, connected, andactivated.

[3457] 2. At some point, the re-synchronizer receives an req_ev_id eventon its in terminal.

[3458] 3. The re-synchronizer sets the asynchronous attribute(async_cplt_attr) in the event bus to indicate that the operation cancomplete asynchronously if needed.

[3459] 4. The event is passed through the out terminal.

[3460] 5. The part connected to the re-synchronizers out terminalreceives the event and returns CMST_PENDING indicating that theoperation will complete asynchronously.

[3461] 6. The re-synchronizer blocks the caller by waiting on an eventsynchronization object.

[3462] 7. At some later point, the re-synchronizer receives a cplt_ev_idevent on its out terminal.

[3463] 8. If the copy_cplt_data property is TRUE, the re-synchronizercopies the completion data into the event bus of the blocked caller.

[3464] 9. If the extract_cplt_s property is TRUE, the re-synchronizerextracts the completion status from the completion data and saves it inits instance data.

[3465] 10. The re-synchronizer unblocks the caller by signaling theevent.

[3466] 11. If the extract_cplt_s property is TRUE, the saved completionstatus is returned to the caller, otherwise CMST_OK is returned.

[3467] 12. Steps 2-11 may be executed many times.

[3468] 13. The re-synchronizer is deactivated, disconnected, anddestroyed.

Unrecognized Events Received on in Terminal

[3469] 1. DM_RSB/DM_RSY is created, connected, and activated.

[3470] 2. At some point, the re-synchronizer receives an unrecognizedevent on its in terminal (any event other than req_ev_id).

[3471] 3. The re-synchronizer forwards the event through the outterminal and returns the results back to the caller.

[3472] 4. Steps 2-3 may be executed many times.

[3473] 5. The re-synchronizer is deactivated, disconnected, anddestroyed.

Unrecognized Events Received on Out Terminal

[3474] 1. DM_RSB/DM_RSY is created, connected, and activated.

[3475] 2. At some point, the re-synchronizer receives an unrecognizedevent on its out terminal (any event other than cplt_ev_id).

[3476] 3. If the re-synchronizer is expecting to receive a completionnotification, it returns CMST_REFUSE. Otherwise, DM_RSB forwards theevent through the in terminal and returns the results back to thecaller. DM_RSY returns CMST_NOT_CONNECTED.

[3477] 4. Steps 2-3 may be executed many times.

[3478] 5. The re-synchronizer is deactivated, disconnected, anddestroyed.

Using Cascaded Re-synchronizers

[3479]FIG. 107 illustrates an advantageous use of the inventive DM_RSBand DM_RSY parts.

[3480] The structure in the figure above is used if there is a need toresynchronize different operations along the same channel. In thisexample, 3 resynchronizers are cascaded—one for each of 3 events thatcan be made to complete asynchronously.

[3481] 1. The structure in FIG. 5 is created, parameterized, andactivated.

[3482] 2. Part A sends an event (e.g., the one that is parameterized onthe second resynchronizer) to the first resynchronizer. Theresynchronizer passes it through the out terminal.

[3483] 3. The second resynchronizer receives the event and passes itthrough the out terminal.

[3484] 4. The third resynchronizer receives the event and passes itthrough the out terminal.

[3485] 5. Part B receives the event and returns CMST_PENDING indicatingthat the operation will complete asynchronously. Control is returned tothe second resynchronizer.

[3486] 6. The second resynchronizer blocks the caller by waiting on anevent synchronization object.

[3487] 7. The asynchronous operation is completed the same way as in theabove use cases.

[3488] 8. The second resynchronizer returns control back to Part A.

[3489] 9. Notes

[3490] 1. If any of the resynchronizers receive cplt_ev_id on its outterminal while it is not expecting asynchronous completion, it willreturn CMST_REFUSE.

[3491] 2. If an event is sent to the resynchronizers in terminal whilethe resynchronizer is waiting for asynchronous completion, the callerwill be blocked until the pending asynchronous operation completes.

[3492] 3. DM_RSY does not enforce the contract ID of the in terminal.The counter terminal of in is expected to be I_DRAIN.

[3493] 4. If an unrecognized event is received on the resynchronizer'sout terminal (while it is not waiting for an asynchronous operation tocomplete), different situations can occurr. DM_RSY will always returnCMST_NOT_CONNECTED and DM_RSB will always pass the event through the interminal.

[3494] 5. The asynchronous operation may be completed by sending thecompletion event to the resynchronizer while in the context of theoperation request.

Buffers DM_SEB—Synchronous Event Buffer

[3495]FIG. 108 illustrates the boundary of the inventive DM_SEB part.

[3496] DM_SEB is a synchronous event buffer with flow control on itsoutput terminal, out. Events are received synchronously at in and areeither passed through to out or are buffered internally until the outputis enabled via ctl.

[3497] The output is enabled or disabled when the EV_REQ_ENABLE andEV_REQ_DISABLE events are received at ctl, respectively.

[3498] When the output is enabled, an event received at in is passedthrough, un-interpreted and un-buffered, to out and runs in the threadof the sender to in. If the output is disabled, all events received byin are buffered until an EV_REQ_ENABLE is received at ctl. On theEV_REQ_ENABLE event, all buffered events are sent out the out terminalin the thread of the EV_REQ_ENABLE sender.

[3499] DM_SEB's output is enabled on activation.

[3500] 1. Boundary

[3501] 1.1. Terminals

[3502] Terminal “in” with direction “In” and contract I_DRAIN. Note:Input for any type of event to be either buffered or passed through. Theevent is not interpreted by DM_SEB.

[3503] Terminal “out” with direction “Out” and contract I_DRAIN. Note:Output for events received at in. Events are output only if the outputis enabled.

[3504] Terminal “ctl” with direction “In” and contract I_DRAIN. Note:Output control. Responds to EV_REQ_ENABLE and EV_REQ_DISABLE events inorder to enable or disable the output.

[3505] 1.2. Events and Notifications Incoming Event Bus Notes EV_REQ_(—)CMEVENT_(—) Changes the state of the output ENABLE HDR to enabled. Allevents received by in after this event are passed through,un-interpreted, to out. EV_REQ_(—) CMEVENT_(—) Changes the state of theoutput DISABLE HDR to disabled. All events received by in after thisevent are buffered on an internal queue and not sent out.

[3506] DM_SEB has no outgoing events.

[3507] 1.3. Special Events, Frames, Commands or Verbs

[3508] None.

[3509] 1.4. Properties

[3510] Property “reset_ev_id” of type “UINT32”. Note: Event ID that willreset DM_SEB before the event is forwarded or buffered. This is aredirected property.

[3511] 2. Encapsulated Interactions

[3512] None.

[3513] 3. Internal Definition

[3514]FIG. 109 illustrates the internal structure of the inventiveDM_SEB part.

[3515] DM_SEB is an assembly that is built entirely out of DriverMagiclibrary parts. It is comprised of a “Desynchronizer with Idle Input”(DWI), which provides the event queue for the assembly, an “IdleGenerator Driven by Event” (IEVx) that provides idle events to dequeueevents buffered in DWI, a “Event Notifier” (NFY) to reset DWI on a highpriority input event and a “Stackable Critical Section” (CRTx), whichguard DM_SEB's inputs, since it has no input operations of its own.

[3516] Events received at in pass through NFY and IEV1 to be enqueued inDWI. If an EV_REQ_ENABLE event has been previously received at ctl, thenIEV1 will generate EV_IDLE events to the event bus, which isparameterized to send the event out its dom terminal first. DWI receivesthe EV_IDLE event from the event bus and de-queues its events inresponse.

[3517] The output is disabled when an EV_REQ_DISABLE event is receivedat ctl. IEV2 passes this event to the event bus, which in turn passes itto both IEV1 and IEV2 at their idle terminals, disabling them. Anyfuture events received at in will pass through NFY and IEV1 to DWI to bebuffered as before, but no EV_IDLE events will be generated by IEV2 orIEV2.

[3518] NFY gives DM_SEB the ability to pass “reset” events immediatelyto its output. It maps an input event, specified by its reset_ev_idproperty, to an EV_RESET event that it sends out its aux terminal, inorder to clear DWI's event queue before it is forwarded to DWI andsubsequently out DM_SEB's out terminal. DWI is guaranteed to receivethis event with an empty queue. The effect of DM_SEB receiving thisevent is that it will be passed through to the output immediately, evenif DWI had other events already enqueued. The reset event is passedthrough DM_SEB's out terminal only if DM_SEB is enabled.

[3519] 4. Subordinate's Responsibilities

[3520] 4.1. CRTx

[3521] 1. Provide a common critical section for all the inputs to theassembly. DM_SEB is a pure assembly and has no guarded input operationsof its own.

[3522] 4.2. IEVx

[3523] 1. Generate EV_IDLE events out its idle terminal in response toany event it receives on its in terminal, if enabled.

[3524] 2. Provide the mechanism to enable and disable idle generation onEV_REQ_xxx events.

[3525] 4.3. DWI

[3526] 1. Implement an event queue that can be consumed with EV_IDLEevents.

[3527] 2. Clear the event queue on receipt of an EV_RESET event

[3528] 4.4. NFY

[3529] 1. Map an input event at its in terminal to an event sent outaux. The input event is forwarded out out either before or after themapped event is sent out aux.

[3530] 5. Subordinate Parameterization Subordinate Property Value DWIqueue_sz 0 (default) disable_idle_req TRUE (default) IEV1 and IEV2idle_first FALSE (default) CRT1 and attr CMCRT_A_NONE (default) CRT2 NFYtrigger_ev EV_NULL (default) pre_ev EV_RESET post_ev EV_NULL (default)EVB sync TRUE dom_first TRUE do_pview FALSE (default) pview_st_okCMST_OK (default) detect FALSE (default) enforce FALSE (default)

[3531] 6. Dominant's Responsibilities

[3532] DM_SEB is a pure assembly; it does not have responsibilities ofits own.

[3533] 7. Internal Interfaces

[3534] All internal interfaces are of type I_DRAIN.

[3535] 8. Theory of Operation

[3536] 8.1. Mechanisms

Event Buffering

[3537] DWI implements an event queue to buffer incoming events. Eventsbuffered by DWI will be sent out out while it receives EV_IDLE events.If the EV_IDLE events have been disabled, DWI will simply add anyincoming events to its queue.

Idle Generation

[3538] Both IEV1 and IEV2 are responsible for generating EV_IDLE eventsfor DM_SEB. IEV1 generates idle events in response to events received atDM_SEB's in terminal and IEV2 generates idles events in response to theEV_REQ_ENABLE event being received at the ctl terminal. In either case,all EV_IDLE events are sent to the event bus for distribution. DWIreceives the EV_IDLE events from the bus and sends any enqueued eventsout DM_SEB's out terminal in response.

Idle Generation Control

[3539] Idle generation is enabled or disabled on EV_REQ_xxx eventsreceived at DM_SEB's ctl terminal. Both IEV1 and IEV2 must beparameterized to generate idle events after passing the input eventthrough.

[3540] When DM_SEB's output is disabled, an EV_REQ_DISABLE event isreceived at ctl that passes through IEV2 to the event bus where it isdistributed to both IEV1 and IEV2, disabling both. No subsequent idlegeneration can occur.

[3541] When an EV_REQ_ENABLE event is received at ctl, it is passesthrough IEV2 to the event bus and is distributed to IEV1 and IEV2's idleterminal, enabling both. When IEV2 receives control back from the eventbus, it generates EV_IDLE events until DWI's queue is emptied and isshut off by DWI. Any subsequent events received at DM_SEB's in terminalwill be enqueued by DWI and will start IEV1's EV_IDLE generator todequeue the event just received by DWI, effectively passing it through.

Handling Reset Events

[3542] NFY is parameterized to map an input event to an EV_RESET eventthat it will send out its aux terminal. When this input event isreceived, NFY first sends an EV_RESET event out aux to clear the eventqueue in DWI and then forwards the event out its out terminal, where iteventually is received by DWI. This clears the way for the input eventto be passed immediately out DM_SEB's out terminal, regardless of howmany events have been previously buffered. The reset event is passedthrough DM_SEB's out terminal only if DM_SEB is enabled.

DM_SEBP—Synchronous Event Buffer with Postpone

[3543]FIG. 110 illustrates the boundary of the inventive DM_SEBP part.

[3544] DM_SEBP is a synchronous event buffer with postpone capabilityand flow control on its output terminal, out. It contains two queues;(a) main queue—queue for buffered events when output is disabled and (b)postponed queue—queue for events that have been postponed.

[3545] Events are received synchronously at in and are either passedthrough to out or are buffered internally on one of SEBP's queues.

[3546] The output is enabled or disabled when the EV_REQ_ENABLE andEV_REQ_DISABLE events are received at ctl, respectively.

[3547] When the output is enabled, an event received at in is passedthrough, un-interpreted and un-buffered, to out and runs in the threadof the sender to in. If the call returns CMST_POSTPONE, the event isbuffered and placed on the postpone queue.

[3548] If the output is disabled, all events received by in are bufferedon the main queue until an EV_REQ_ENABLE event is received at ctl. Onthe EV_REQ_ENABLE event, all buffered events are sent out the outterminal in the thread of the EV_REQ_ENABLE sender.

[3549] If an EV_FLUSH event is received at ctl, the buffered events onthe postpone queue are moved to the front of the main queue and are sentout the out terminal in the thread of the EV_FLUSH sender.

[3550] When the output is disabled, a single event may be dequeued fromthe main queue and sent out the out terminal by sending an EV_IDLE eventto the ctl terminal. The event is sent out the out terminal in thethread of the EV_IDLE sender.

[3551] DM_SEBP's output is enabled on activation.

[3552] 9. Boundary

[3553] 9.1. Terminals

[3554] Terminal “in” with direction “In” and contract I_DRAIN. Note:Input for any type of event to be either buffered or passed through. Theevent is not interpreted by DM_SEBP.

[3555] Terminal “out” with direction “Out” and contract I_DRAIN. Note:Output for events received at in. Events are output only if the outputis enabled or an EV_FLUSH or EV_IDLE event is received on ctl.

[3556] Terminal “ctl” with direction “In” and contract I_DRAIN. Note:Input for output control events.

[3557] 9.2. Events and Notifications

[3558] The following events are recognized on the in terminal: IncomingEvent Bus Notes (reset_(—) CMEVENT_(—) DM_SEBP is parameterized withthis event ev_id) HDR via its reset_ev_id property. When this event isreceived, DM_SEBP empties both of its queues and forwards the event toout (if it is enabled). If DM_SEBP is disabled, the event is placed onthe main queue. This event does not affect the enabled/disabled state ofDM_SEBP

[3559] The following events are recognized on the ctl terminal: IncomingEvent Bus Notes EV_REQ_(—) CMEVENT_(—) Changes the state of the outputto enabled. ENABLE HDR All events received on in, after this event, arepassed through, un-interpreted, to out. EV_REQ_(—) CMEVENT_(—) Changesthe state of the output DISABLE HDR to disabled. All events received byin after this event are buffered on the main queue and not sent out.EV_FLUSH CMEVENT_(—) Move postponed events to the beginning HDR of themain queue and if enabled, send all events to out. This event does notaffect the enabled/ disabled state of SEBP EV_IDLE CMEVENT_(—) Remove asingle event from HDR the main queue and send it to out. The returnstatus is CMST_OK or CMST_(—) NO_ACTION. This event does not affect theenabled/ disabled state of SEBP. EV_RESET CMEVENT_(—) Empty the main andpostpone queues HDR (i.e., lose the events). This event does not affectthe enabled/ disabled state of SEBP.

[3560] DM_SEBP has no outgoing events.

[3561] 9.3. Special Events, Frames, Commands or Verbs

[3562] None.

[3563] 9.4. Properties

[3564] Property “reset_ev_id” of type “UINT32”. Note: Event ID that willreset DM_SEBP before the event is forwarded or buffered. This is aredirected property.

[3565] 10. Internal Definition

[3566]FIG. 111 illustrates the internal structure of the inventiveDM_SEBP part.

[3567] 11. Functional Overview

[3568] DM_SEBP is an assembly whose behavior is built entirely, withoutspecific code, by assembling DriverMagic library parts.

[3569] Events received at in pass through NFY1 and IEV1 to be enqueuedin the main desynchronizer, DWI1. If an EV_REQ_ENABLE event has beenpreviously received at ctl, then IEV1 will generate EV_IDLE events tothe event bus, which is parameterized to send the event out its domterminal first. DWI1 receives the EV_IDLE event from the event bus,dequeues its events in response, and sends subsequent events out. Whenthe status returned from out is CMST_POSTPONE, DSV interprets thisstatus to mean the event was not serviced and sends the event to itsout2 terminal, resulting in the event being enqueued in the postponedesynchronizer, DWI2.

[3570] The output is disabled when an EV_REQ_DISABLE event is receivedat ctl. The event is passed to IEV2, which passes this event to theevent bus, which in turn passes it to IEV1, IEV2, and IEV3 at their idleterminals, disabling them. Any future events received at in will passthrough NFY1 and IEV1 to DWI1 to be buffered as before, but no EV_IDLEevents will be generated by IEV1.

[3571] When an EV_REQ_ENABLE event is received at ctl, it is passed toIEV2, which is parameterized to forward it out its out terminal beforesending EV_IDLE events out its idle terminal. The event passes to themain desynchronizer, DWI1, and enables it. IEV2 then generates EV_IDLEevents out its idle terminal resulting in DWI1 sending each of itsqueued events out.

[3572] When an EV_FLUSH event is received at ctl, it is passed to IEV3,which is parameterized to forward it to its out terminal before sendingEV_IDLE events out its idle terminal. The event passes to NFY2, whichrecognizes it and generates an EV_REQ_DISABLE event resulting in MUXswitching its output to out2. The EV FLUSH event is then sent to IEV4,which generates EV IDLE events causing DWI1 to dequeue all of itsbuffered events. The dequeued events pass through MUX and aresubsequently enqueued in DWI2. IEV4 then passes the event to NFY3, whichissues an EV_REQ_ENABLE event out its aux terminal to switch MUX'soutput back to out1. NFY3 then passes the EV_FLUSH to IEV5, whichgenerates EV_IDLE events and causes DWI2 to dequeue all of its eventsinto DWI1. As a result, all previously-postponed events are placed atthe head of the queue in DWI1. When the EV_FLUSH event returns to IEV3,If DM_SEBP is enabled, IEV3 generates EV_IDLE events to the event buscausing DWI1 to dequeue all of its events.

[3573] When DM_SEBP receives the event specified by its reset_ev_idproperty, NFY1 generates an EV_RESET event to the event bus, causingDWI1 and DWI2 to empty their queues before the event is passed on. IfDM_SEBP is disabled, the event that generated the “reset” event will beenqueued in DWI1.

[3574] 12. Subordinate's Responsibilities

[3575] 12.1. CRT—Stackable Critical Section

[3576] 1. Provide a common critical section for all the inputs to theassembly. DM_SEBP is a pure assembly and has no guarded input operationsof its own.

[3577] 12.2. SPL—Event Splitter

[3578] 1. Filters out specified events and send them out its auxterminal. All other events are sent out its out terminal.

[3579] 12.3. NFY—Event Notifyier

[3580] 2. Generates an event out aux when a specific event is receivedon in. The input event is forwarded out out either before or after thegenereated event is sent out aux.

[3581] 12.4. IEV—Idle by Event

[3582] 1. Generate EV_IDLE events out its idle terminal in response toany event it receives on its in terminal, if enabled.

[3583] 2. Provide the mechanism to enable and disable idle generation onEV_REQ_XXX events.

[3584] 12.5. DWI—Desynchronizer with Idle Input

[3585] 1. Implement an event queue that can be pumped with EV_IDLEevents.

[3586] 2. Clear the event queue on receipt of an EV_RESET event

[3587] 12.6. BSP—Bi-directional Splitter

[3588] 1. Provide plumbing to enable connection of a bi-directionalterminal to an unidirectional input or output.

[3589] 12.7. STP—Event Stopper

[3590] 1. Terminate the event flow by returning a specified status(e.g., CMST_OK).

[3591] 12.8. MUX—Event-Controlled Multiplexer

[3592] 1. Implements a switch between its out1 and out2 outputs that iscontrolled by event input on its ctl terminal.

[3593] 12.9. DSV—Distributor for Service

[3594] 1. Forwards incoming operation to out2 if the operation is notserviced by out1.

[3595] 13. Distribution of Properties Property Distr. Subordinatereset_ev_id Redirected nfy1.trigger_ev

[3596] 14. Subordinate Parameterization Part Property Value crt1, crt2attr GMCRT_A_NONE (default) s1 ret_s CMST_NOT_SUPPORTED s2, s3 ret_sCMST_OK spl1 ev_min EV_RESET ev_max EV_RESET spl2 ev_min EV_IDLE ev_maxEV_IDLE spl3 ev_min EV_REQ_ENABLE ev_max EV_REQ_DISABLE spl4 ev_minEV_FLUSH ev_max EV_FLUSH nfy1 trigger_ev EV_NULL (exposed asreset_ev_id) pre_ev EV_RESET post_ev EV_NULL nfy2 trigger ev EV_FLUSHpre_ev EV_REQ_DISABLE post_ev EV_NULL nfy3 trigger_ev EV_FLUSH pre_evEV_REQ_ENABLE post_ev EV_NULL iev1 idle_first FALSE iev2 idle_firstFALSE iev3 idle_first FALSE iev4 idle_first TRUE iev5 idle_first TRUEdwi queue_sz 0 (default) disable_idle_req TRUE (default) evb sync TRUEdom_first TRUE do_preview FALSE (default) mux ev_out1 EV_REQ_ENABLEev_out2 EV_REQ_DISABLE dsv hunt_stat CMST_POSTPONE hunt_if_match TRUE

[3597] 15. Internal Interfaces

[3598] All internal interfaces are of type I_DRAIN.

[3599] 16. Theory of Operation

[3600] 16.1. Mechanisms

Event Buffering

[3601] DWI implements an event queue to buffer incoming events. Eventsbuffered by DWI will be sent out out while it receives EV_IDLE events.If the EV_IDLE events have been disabled, DWI will simply add anyincoming events to its queue.

[3602] When the queue in DWI is empty, it will return CMST_NO_ACTION,causing the EV_IDLE generation to be stopped.

Idle Generation

[3603] All of the IEVx parts are responsible for generating EV_IDLEevents for DM_SEBP. IEV1 generates idle events in response to eventsreceived at DM_SEBP's in terminal. IEV2 generates idles events inresponse to the EV_REQ_ENABLE event being received at the ctl terminal.IEV3 generates idle events to empty DWI1's queue after an EV_FLUSH eventhas been received on ctl. IEV4 generates idle events to move thecontents of DWI2's queue to DWI1 after an EV_FLUSH event, and IEV5generates the idle events to move the contents of DW1's queue to the endof DWI2's queue after an EV_FLUSH event has been received on ctl.

[3604] In all cases, all EV_IDLE events are sent to the event bus fordistribution. DWI1 receives the EV_IDLE events from the bus and sendsany enqueued events out DM_SEBP's out terminal in response. DWI2receives EV_IDLE events only from IEV5.

Idle Generation Control

[3605] Idle generation is enabled or disabled on EV_REQ_ENABLE/DISABLEevents received at DM_SEBP's ctl terminal. When DM_SEBP's output isdisabled, an EV_REQ_DISABLE event is received at ctl that passes throughIEV2 to the event bus where it is distributed to IEV1, IEV2, and IEV3,disabling all. No subsequent idle generation can occur. When anEV_REQ_ENABLE event is received at ctl, it passes through IEV2 to theevent bus and is distributed to IEV1, IEV2 and IEV3's idle terminal,enabling all. When IEV2 receives control back from the event bus, itgenerates EV_IDLE events until DWI1's queue is emptied and is shut offby DWI1. Any subsequent events received at DM_SEBP's in terminal will beenqueued by DWI and will start IEV1's EV_IDLE generator to dequeue theevent just received by DWI1, effectively passing it through.

Flushing Postponed Events

[3606] When an EV_FLUSH event is received at ctl, it is passed throughIEV3, which passes to IEV4 via NFY2. IEV4 generates EV_IDLE events untilDWI1's queue is emptied into DWI2's queue. The event is then passed toIEV5 which generates EV_IDLE events until DWI2's queue is emptied backinto DWI1's (i.e. moving contents of DWI2 in front of DWI1). When IEV3regains control, it generates EV_IDLE events, if it is enabled, to theevent bus until DWI1's queue is emptied and is shut off by DWI1.

Postponing Operations

[3607] When a forwarded event returns CMST_POSTPONE, that event isenqueued onto DWI2's queue until an EV_FLUSH event is received on ctl.When the EV_FLUSH event is received, the contents of DWI2's queue aremoved to the front of DWI1's queue and all events are sent out out ifDM_SEBP is enabled.

[3608] 16.2. Use Cases

[3609]FIG. 112 illustrates an advantageous use of the inventive DM_SEBPpart.

Preventing Re-entrancy

[3610] When PART1 does not wish to receive events on in terminal whileprocessing an event, it can disable its event input by sending anEV_REQ_DISABLE event out its ctl terminal. When PART1 is finishedprocessing the event, it sends an EV_REQ_ENABLE event out its ctlterminal to re-enable its event input before returning.

Postponing Operations

[3611] If PART1 is in a state where it cannot process certain events, itdoesn't want them discarded, and it does not want to prevent furtherevents from coming in, it can postpone delivery of those events byreturning a CMST_POSTPONE status. This causes DM_SEBP to enqueue theevent on its postpone queue. PART1 is able process the postponed events,it sends an EV_FLUSH event out its ctl terminal. This causes DM_SEBP todequeue each of the postponed events one at a time and send them toPART1's in terminal.

DM_ASB—Asymmetrical Synchronous Buffer

[3612]FIG. 113 illustrates the boundary of the inventive DM_ASB part.

[3613] DM_ASB is an asymmetrical synchronous event buffer. Flow controlis provided for events moving in the forward direction (e.g., from in toout). The flow of events out of out can be disabled by sendingEV_REQ_ENABLE and EV_REQ_DISABLE events to ctl. While disabled, eventssent to DM_ASB in the forward direction are buffered until the output isre-enabled.

[3614] All events sent to DM_ASB in the reverse direction areimmediately passed through without any buffering.

[3615] 17. Boundary

[3616] 17.1. Terminals

[3617] Terminal “in” with direction “Bidir” and contract I_DRAIN . Note:Forward event I/O terminal.

[3618] Terminal “out” with direction “Bidir” and contract I_DRAIN. Note:Reverse event I/O terminal.

[3619] Terminal “ctl” with direction “In” and contract I_DRAIN . Note:Flow control. Responds to EV_REQ_ENABLE and EV_REQ_DISABLE events inorder to enable or disable the output.

[3620] 17.2. Events and Notifications Incoming Event Bus NotesEV_REQ_(—) CMEVENT_(—) Changes the state of the output to enabled.ENABLE HDR All forward events are passed through, un-interpreted, toout. EV_REQ_(—) CMEVENT_(—) Changes the state of the output to DISABLEHDR disabled. All forward events are buffered on an internal queue andnot sent out.

[3621] DM_ASB has no outgoing events.

[3622] 17.3. Special Events, Frames, Commands or Verbs

[3623] None.

[3624] 17.4. Properties

[3625] Property “reset_ev_id” of type “UINT32”. Note: Event ID that willreset DM_ASB before the event is forwarded or buffered. This is aredirected property.

[3626] 18. Internal Definition

[3627]FIG. 114 illustrates the internal structure of the inventiveDM_ASB part. DM_ASB is a pure assembly and has no functionality of itsown. Refer to the DM_SEB Data Sheet for a detailed functional overviewof the event buffer.

[3628] 19. Subordinate's Responsibilities

[3629] 19.1. BSP—Bi-directional Splitter

[3630] Split event flow between a single bi-directional interface and aninput/output interface pair.

[3631] 19.2. SEB—Synchronous Event Buffer

[3632] See the description of DM_SEB for a detailed functional overviewof the event buffer.

DM_ASBR, DM_ASBR2—Asymmetrical Synchronous Buffer for Requests

[3633]FIG. 115 illustrates the boundary of the inventive DM_ASBR2 part.DM_ASBR/DM_ASBR2 are asymmetrical synchronous buffers for requests. Flowcontrol is provided for requests moving in the forward direction (e.g.,from in to out). The flow of events out of out can be disabled bysending EV_REQ_ENABLE and EV_REQ_DISABLE events to ctl. While disabled,requests sent to DM_ASBR/DM_ASBR2 in the forward direction are buffereduntil the output is re-enabled.

[3634] When DM_ASBR/DM_ASBR2 stores a request in self, it sends backstatus CMST_PENDING. This status notifies the sender of the request thatthe request will be completed later by sending the same request backwith CMEVT_A_COMPLETED attribute set.

[3635] DM_ASBR/DM_ASBR2 always completes the incoming requests with acompletion event. If the part connected to out completes the eventsynchronously, DM_ASBR/DM_ASBR2 generates a completion event and returnsCMST_PENDING.

[3636] DM_ASBR/DM_ASBR2 always use an incoming event—either from in orfrom ctl to send queued events to out.

[3637] All request completions sent in the reverse direction areimmediately passed through without any buffering.

[3638] Note that DM_ASBR/DM_ASBR2 assumes without assertion that theCMEVT_A_ASYNC_CPLT bit is set on incoming events.

[3639] DM_ASBR2 should be used in all new designs. DM_ASBR does notcomply with the proper event completion disipline and is provided onlyfor compatibility for older projects.

[3640] 20. Boundary

[3641] 20.1. Terminals

[3642] Terminal “in” with direction “Bidir” and contract I_DRAIN. Note:Forward event I/O terminal.

[3643] Terminal “out” with direction “Bidir” and contract I_DRAIN. Note:Reverse event I/O terminal.

[3644] Terminal “ctl” with direction “In” and contract I_DRAIN. Note:Flow control. Accepts to EV_REQ_ENABLE and EV_REQ_DISABLE events inorder to enable or disable the output.

[3645] 20.2. Events and Notifications

[3646] The following events can be received on the ctl terminal:Incoming Event Bus Notes EV_REQ_(—) CMEVENT_(—) Changes the state of theoutput to enabled. ENABLE HDR All forward events are passed through out.EV_REQ_(—) CMEVENT_(—) Changes the state of the output to DISABLE HDRdisabled. All forward events are buffered on an internal queue and notsent out.

[3647] All events received on the in terminal are eventually forwardedto out. All events (typically request completions) received on the outterminal are immediately sent through the in terminal.

[3648] 20.3. Special Events, Frames, Commands or Verbs

[3649] None.

[3650] 20.4. Properties (DM_ASBR)

[3651] Property “reset_ev_id” of type “UINT32”. Note: Event ID that willreset DM_ASBR before the event is forwarded or buffered. Not availableon DM_ASBR2. Default is EV_NULL.

[3652] Property “cplt_s_offs” of type “UINT32”. Note: Offset in bytes ofthe completion status in the event bus. Mandatory.

[3653] 21. Encapsulated Interactions

[3654] None.

[3655] 22. Internal Definition (DM_ASBR2)

[3656]FIG. 116 illustrates the internal structure of the inventiveDM_ASBR2 part.

[3657] DM_ASBR2 is an assembly that is built entirely out of DriverMagiclibrary parts. It comprises a “Fundamental Desynchronizer” (FDSY), whichprovides the event queue for the assembly; two “Idle Generator Driven byEvent” (IEVx) that provide idle events to dequeue events buffered inFDSY; a “Stackable Critical Section” (CRTx), which guards DM_ASBR2'sinputs, since it has no input operations of its own; and an“Asynchronous Completer” (ACT) used to convert synchronous completionsto asynchronous.

[3658] Events received at in pass through iev_in to be enqueued in FDSY.If an EV_REQ_ENABLE event has been previously received at ctl, theniev_in will generate EV_IDLE events to the event bus, which isparameterized to send the event out its dom terminal first. FDSYreceives the EV_IDLE event from the event bus and de-queues its eventsin response.

[3659] The output is disabled when an EV_REQ_DISABLE event is receivedat ctl. iev_ctl passes this event to the event bus, which in turn passesit to both iev_in and iev_ctl at their idle terminals, disabling them.Any future events received at in will pass through IEV1 to FDSY to bebuffered as before, but no EV_IDLE events will be generated by iev_in oriev_ctl.

[3660] 23. Subordinate's Responsibilities

[3661] 23.1. DM_BSP—Bi-directional Splitter

[3662] 1. Split event flow between a single bi-directional interface andan input/output interface pair.

[3663] 23.2. DM_ACT—Asynchronous Completer

[3664] 1. Transform synchronous completion of an outgoing event intoasynchronous completion.

[3665] 23.3. DM_CRT—Stackable Critical Section

[3666] 1. Provide a common critical section for all the inputs to theassembly.

[3667] DM_ASBR2 is a pure assembly and has no guarded input operationsof its own.

[3668] 23.4. DM [EV—Idle by Event

[3669] 1. Generate EV_IDLE events out its idle terminal in response toany event it receives on its in terminal, if enabled.

[3670] 2. Provide the mechanism to enable and disable idle generation onEV_REQ_xxx events.

[3671] 23.5. DM_FDSY—Fundamental Desynchronizer

[3672] 1. Implement an event desynchronizer which sends out queuedevents when it receives EV_IDLE or EV_PULSE on its control terminal.

[3673] 2. Clear the event queue on receipt of an EV_RESET event

[3674] 23.6. DM_SPL—Event Flow Splitter

[3675] 1. Split the incoming event flow into a main flow and an auxilaryflow.

[3676] 23.7. DM_DST—Drain Stopper

[3677] 1. Consume all events received on its terminal.

[3678] 24. Dominant's Responsibilities

[3679] 24.1. Hard Parameterization of Subordinates Subordinate PropertyValue FDSY ok_stat CMST_PENDING disable_ctl_req TRUE SPL ev_minEV_REQ_ENABLE ev_max EV_REQ_DISABLE ACT enforce_async TRUE EVB sync TRUEdom_first TRUE

[3680] 24.2. Distribution of Properties to the Subordinates

[3681] Property “cplt_s_offs” of type “UINT32”. Note: rediract.cplt_s_offs

[3682] 25. Theory of Operation

[3683] 25.1. Mechanisms

Event Buffering

[3684] FDSY implements an event queue to buffer incoming events. Eventsbuffered by FDSY will be sent out out when it receives EV_IDLE events.If the EV_IDLE events have been disabled, FDSY will simply add anyincoming events to its queue.

Idle Generation

[3685] Both iev_in and iev_ctl are responsible for generating EV_IDLEevents for DM_ASBR2. iev_in generates idle events in response to eventsreceived at DM_ASBR2's in terminal and iev_ctl generates idles events inresponse to the EV_REQ_ENABLE event being received at the ctl terminal.In either case, all EV_IDLE events are sent to the event bus fordistribution. FDSY receives the EV_IDLE events from the bus and sendsany enqueued events out DM_ASBR2's out terminal in response.

Idle Generation Control

[3686] Idle generation is enabled or disabled on EV_REQ_xxx eventsreceived at DM_ASBR2's ctl terminal. Both iev_in and iev_ctl must beparameterized to generate idle events after passing the input eventthrough.

[3687] When DM_ASBR2's output is disabled, an EV_REQ_DISABLE event isreceived at ctl that passes through iev_ctl to the event bus where it isdistributed to both iev_in and iev_ctl, disabling both. No subsequentidle generation can occur.

[3688] When an EV_REQ_ENABLE event is received at ctl, it is passedthrough iev_ctl to the event bus and is distributed to iev_in andiev_ctl's idle terminal, enabling both. When iev_ctl receives controlback from the event bus, it generates EV_IDLE events until FDSY's queueis emptied and is shut off by FDSY. Any subsequent events received atDM_ASBR2's in terminal will be enqueued by FDSY and will start iev_in'sEV_IDLE generator to dequeue the event just received by FDSY,effectively passing it through.

[3689] 26. Functional Overview of the DM_ASBR Buffer

[3690]FIG. 117 illustrates the internal structure of the inventiveDM_ASBR part.

[3691] Refer to the DM_SEB Data Sheet for a detailed functional overviewof the event buffer.

[3692] 27. Subordinate's Responsibilities

[3693] 27.1. DM BSP—Bi-directional Splitter

[3694] Split event flow between a single bi-directional interface and aninput/output interface pair.

[3695] 27.2. DM_ACT—Asynchronous Completer

[3696] Transform synchronous completion of an outgoing event intoasynchronous completion of the incoming event that generated the former.

[3697] 27.3. DM_ERC—Event Recoder

[3698] Remap incoming event IDs and attributes and pass them out.

[3699] 27.4. DM_STX—Status Recoreder

[3700] 1. Re-code the event processing return status s1 (from the outterminal) to s2

[3701]2. Forward all events received from the in terminal through theout terminal.

[3702] 27.5. DM_RPL—Event Replicator

[3703] 1. Pass all events coming on in to out

[3704] 2. Duplicate events coming on in and send the duplicates to aux.

[3705] 28. Dominant's Responsibilities

[3706] 28.1. Hard Parameterization of Subordinates Part Property Valuestx s1 CMST_OK s2 CMST_PENDING act enforce_async FALSE seta in_base 0out_base 0 n_events 0xFFFFFFFF or_attr CMEVT_A_ASYNC_CPLT and_attr˜CMEVT_A_SELF_OWNED clra in_base 0 out_base 0 n_events 0xFFFFFFFFor_attr CMEVT_A_SELF_OWNED and_attr ˜CMEVT_A_ASYNC_CPLT rpl_stx s1CMST_PENDING s2 CMST_OK rpl_stp ret_s CMST_OK

[3707] 28.2.

[3708] 28.3. Distribution of Properties to the Subordinates PropertyName Type Dist To reset_ev_id UINT32 redir seb.reset_ev_id cplt_s_offsUINT32 redir act.cplt_s_offs

Interaction Serializers DM_ESL—Event Serializer

[3709]FIG. 118 illustrates the boundary of the inventive DM_ESL part.

[3710] DM_ESL serializes a flow of IRP events whenever these events areprocessed asynchronously. DM_ESL does not send the next event throughits output until the processing of the preceding one is complete.

[3711] While asynchronous events sent through the out terminal are beingprocessed, the events, coming at the in terminal, are buffered until thecompletion event arrives at the back channel of out.

[3712] In case the completion of the output event is synchronous, thenext event from the buffer (if any) is sent to out immediately and thesame procedure is commenced.

[3713] Effectively, DM_ESL ensures that there is only one event sent tothe out terminal that awaits completion. In the meantime all incomingevents are buffered for further processing.

[3714] Note: This part cannot be used (fed) with events that are notallowed to complete asynchronously. If necessary, insert an instance ofDM_RSB at the front, which will effectively eliminate this limitation.For more information, refer to the DM_RSB data sheet.

[3715] 1. Boundary

[3716] 1.1. Terminals

[3717] Terminal “in” with direction “Plug” and contract I_DRAIN. Note:Incoming IRP events (EV_REQ_IRP). The back channel of this terminal isused for completion events only. Can be connected at Active Time.

[3718] Terminal “out” with direction “Plug” and contract I_DRAIN. Note:All events that are not processed are passed through here. The backchannel receives the completion events (if completed asynchronously).

[3719] 1.2. Events and Notifications Passed Through the “in” TerminalIncoming Event Bus Notes EV_REQ_IRP B_EV_IRP Indicates that IRP needsprocessing. Outgoing Event Bus Notes EV_REQ_IRP B_EV_IRP Indicates thatIRP processing has completed. This event is the same event that wasprocessed asynchronously with CMEVT_A_COMPLETED attribute set.

[3720] 1.3. Events and Notifications Passed Through the “out” TerminalOutgoing Event Bus Notes EV_REQ_IRP B_EV_IRP Indicates that IRP needsprocessing.

[3721] Incoming Event Bus Notes EV_REQ_IRP B_EV_IRP Indicates that IRPprocessing has completed. This event usually is the same event as (or acopy of) the event that was processed asynchronously withCMEVT_A_COMPLETED attribute set.

[3722] 1.4. Special Events, Frames, Commands or Verbs

[3723] None.

[3724] 1.5. Properties

[3725] None.

[3726] 2. Encapsulated Interactions

[3727] DM_ESL is an assembly and does not have encapsulatedinteractions. Its subordinates, however, may have such depending ontheir implementation. For more information on the subordinates, pleaserefer to the data sheets of:

[3728] DM_BSP

[3729] DM_STX

[3730] DM_ASB

[3731] DM_EPP

[3732] DM_ACT

[3733] 3. Internal Definition

[3734]FIG. 119 illustrates the internal structure of the inventiveDM_ESL part.

[3735] 4. Theory of Operation

[3736] DM_ESL is an assembly. It contains an asynchronous event buffer(DM_ASB), Event Popper (DM_EPP) and Asynchronous Completer (DM_ACT).

[3737] The parts in Block B implement the main functionality in thisassembly—event buffering and serialization on completion.

[3738] DM_EPP disables (shuts off) the event flow coming to its interminal after passing an event to out and awaits for an event to comeon the back channel, upon which it enables the input flow again.

[3739] This procedure when used in conjunction with DM_ASB (as shownabove) ensures that incoming events are properly buffered during theprocessing of the event.

[3740] Parts in Block A and DM_ACT condition/transform the bidirectionalevent flow, to ensure that the whole assembly operates normally. DM_ACTtransforms synchronously completed events on its out terminal intoevents completed asynchronously on the in terminal.

[3741] The purpose of Block A is to recode the event distribution statusreturned by the in terminal of DM_ASB into CMST_PENDING for the purposesof asynchronous event completion.

[3742] For more details on DM_ASB, DM_ACT and DM_EPP, refer to theirdata sheets.

[3743] 4.1. Subordinate Parameterization Subordinate Property Value STXs1 CMST_OK s2 CMST_PENDING ACT cplt_s_offs offsetof (B_EV_IRP, cplt_s)

DM_RSL—Request Serializer

[3744]FIG. 120 illustrates the boundary of the inventive DM_RSL part.

[3745] DM_RSL is a serializer for asynchronous requests. It is used incases where it is necessary to guarantee that a server of asynchronousrequests is not going to receive a new request until it has completedthe previous one.

[3746] DM_RSL is limited to serializing a single type of requests, therequest type (event ID) that it accepts is programmable through aproperty. The inputs of DM_RSL are callable only in normal thread time.A caller's thread may be blocked if another thread has already enteredthe assembly. Since DM_RSL may call its outputs while its criticalsection is acquired, the possibility of deadlocks should be consideredwhen using this part—see the Specification section below for details.

[3747] DM_RSL is an assembly made entirely of standard DriverMagiclibrary parts, as shown on the diagram. It may be used in any operatingenvironment supported by DriverMagic. The Specification section belowdescribes in detail the operation of DM_RSL.

[3748] 5. Boundary

[3749] 5.1. Terminals

[3750] Terminal “in” with direction “i/o” and contract I_DRAIN. Note:Request input. Requests on this input may arrive in any order, whetheror not previous requests have been completed. All requests sent to thisinput must have the event ID specified by the evt id property and mustbe desynchronizable—i.e., they should have the CMEVT_A_ASYNC_CPLTattribute set and should not be allocated on the stack. Note that a sideeffect of the operation of DM_RSY is that all requests submitted to incomplete asynchronously.

[3751] Terminal “out” with direction “i/o” and contract I_DRAIN. Note:Serialized request output. Requests received from in are sent to out oneby one, a second request is not sent until the previous one hascompleted.

[3752] 5.2. Properties

[3753] Property “evt_id” of type “uint32”. Note: Specifies the value ofthe id field of the requests sent to in. Note that requests with adifferent ID or other events should not be sent to DM_RSL's in terminal.Default value: EV_REQ_IRP

[3754] Property “cplt_s_offs” of type “uint32”. Note: Specifies theoffset in the request bus where the completion status is stored. Defaultvalue: offsetof(B_EV_IRP, cplt_s).

[3755] 6. Encapsulated Interactions

[3756] None.

[3757] 7. Specification

[3758]FIG. 121 illustrates the internal structure of the inventiveDM_RSL part.

[3759] 8. Responsibilities

[3760] Serialize asynchronous requests coming on the in terminal andforward them to out, so that a part attached to out does not receivemore than one request at a time. Use a queue to store additionalrequests, while one is pending on the out terminal.

[3761] 9. Theory of Operation

[3762] The state of DM_RSL is kept by the DM_MUX part:

[3763] ON state (this is the initial state)—DM_MUX has out1 enabled;this state represents tha case when there are no pending requests beingprocessed by the part connected to DM_RSL's out terminal. A request thatcomes to in in this state is forwarded directly to out.

[3764] OFF state—DM_MUX has out2 enabled; this state represents the casewhen there is a pending request. In this state, new requests that cometo in are queued by DM_RSL in the DM_FDSY part.

[3765] The operation of DM_RSL is illustrated by the following twocases.

[3766] 9.1. Case 1: requests come on the in terminal in sequence

[3767] The first request that enters DM_RSL comes when the assembly isin the ON state—the request bypasses the DM_FDSY queue and is forwardedto out. On its way it passes through the OFF event generator—DM_NFY,programmed to emit an EV_REQ_DISABLE event, which causes DM_MUX toswitch to out2 (DM_RSL enters the OFF state).

[3768] The completion of the request goes through the “completed” eventgenerator—DM_NFY, programmed to emit an EV_PULSE event after the requestcompletion has been sent back to DM_RSL's in terminal. The EV_PULSEevent goes first through the ON event generator that sends anEV_REQ_ENABLE to the DM_MUX, switching it back to the ON state, and thengoes to the queue (DM_FDSY). Since there are no requests queued thelatter has no effect.

[3769] Now DM_RSL has returned to its original state and can process thenext incoming request in the same manner.

[3770] 9.2. Case 2: New Requests Come on the In Terminal Before theFirst One has Completed

[3771] When the first request comes, the events that take place inDM_RSL are the same as described in the 1^(st) step in Case 1 above.

[3772] When a second request comes on in before the first one hascompleted, DM_RSL is in its OFF state—DM_MUX has its out2 opened, so theincoming request is enqueued in DM_FDSY and CMST_PENDING is returned tothe client.

[3773] If more requests come before the first one has completed, theyare enqueued as well.

[3774] When the completion of the request comes on out (or is generatedby DM_ACT), it goes through the “completed” event generator—DM_NFY,programmed to emit an EV_PULSE event after the request completion hasbeen sent back to DM_RSL's in terminal. The EV_PULSE event goes firstthrough the ON event generator that sends an EV_REQ_ENABLE to theDM_MUX, switching it back to the ON state, and then goes to the queue(DM_FDSY). DM_FDSY dequeues one request and sends it out.

[3775] The dequeued request immediately switches DM_RSL back to its OFFstate.

[3776] The above two steps are repeated until there are no more requestsin the queue. The completion of the last request switches DM_RSL to itsON state, exactly as in step #2 of Case 1 above. DM_RSL remains in thisstate until new requests come to the in terminal.

[3777] 9.3. Critical Section Guard in DM_RSL

[3778] The group of parts in DM_RSL that keeps its state (DM_MUX andDM_FDSY) is guarded by the two connected DM_CRT parts, which act as asingle critical section that surrounds this group. This is done toguarantee that the sequence of execution is always going to be asdescribed in the two cases above, even if a second thread of executionenters DM_RSL.

[3779] Note that the thread of execution that goes to the out terminalalways owns DM_RSL's critical section. DM_RSL calls out in the followingtwo different situations, in both cases within its critical section:

[3780] with a request that came on in while DM_RSL was in the ON state

[3781] with a dequeued request when called on out with the completion ofthe previous request—in this case the part connected to out isre-entered in the same thread of execution that it used to send theprevious request's completion.

[3782] A request completion coming on out is forwarded to in firstwithout entering DM_RSL's guard—see diagram. However, DM_RSL may callback in with a request completion while its guard is acquired if thatcompletion happens in the thread of the original request (e.g., if thecompletion is generated by DM_ACT).

[3783] 10. Subordinate Parameterization Subordinate Property Value muxev_out1 EV_REQ_ENABLE (DM_MUX) ev_out2 EV_REQ_DISABLE quedisable_ctl_req TRUE (DM_FDSY) ok_stat CMST_PENDING off trigger_evEV_REQ_IRP (DM_NFY) pre_ev DM_REQ_DISABLE on trigger_ev EV_PULSE(DM_NFY) pre_ev DM_REQ_ENABLE cplt trigger_ev EV_REQ_IRP (DM_NFY)post_ev EV_PULSE act cplt_s_offs offsetof(B_EV_IRP, (DM_ACT) cplt_s)

DM_EPP—Event Popper

[3784]FIG. 122 illustrates the boundary of the inventive DM_EPP part.

[3785] DM_EPP is an IRP event popper. It uses an external flow controlto disable and enable the incoming flow of events, so that there is onlyone IRP event, which awaits completion.

[3786] DM_EPP expects that all events sent through out will completeasynchronously. Naturally, DM_EPP also expects that the incoming eventswill be allowed to complete asynchronously. If any of these conditionsare not satisfied, the proper operation of DM_EPP cannot be guaranteed³.

[3787] DM_EPP sends requests to enable or disable the event flow throughthe flw terminal and expects that the part connected there will alwayssucceed to do that

[3788] 11. Boundary

[3789] 11.1. Terminals

[3790] Terminal “in” with direction “Plug” and contract I_DRAIN. Note:Incoming IRP events (EV_REQ_IRP). The back channel of this terminal isused for completion events only. Can be connected at Active Time.

[3791] Terminal “out” with direction “Plug” and contract I_DRAIN. Note:All events that are not processed are passed through here. The backchannel receives the completion events (if completed asynchronously).

[3792] 11.2. Events and Notifications Passed Through the “in” TerminalIncoming Event Bus Notes EV_REQ_IRP B_EV_IRP Indicates that IRP needsprocessing.

[3793] Outgoing Event Bus Notes EV_REQ_IRP B_EV_IRP Indicates that IRPprocessing has completed. This event is the same event that wasprocessed asynchronously with CMEVT_A_COMPLETED attribute set.

[3794] 11.3. Events and Notifications Passed Through the “out” TerminalOutgoing Event Bus Notes EV_REQ_IRP B_EV_IRP Indicates that IRP needsprocessing.

[3795] Incoming Event Bus Notes EV_REQ_IRP B_EV_IRP Indicates that IRPprocessing has completed. This event usually is the same event as (or acopy of) the event that was processed asynchronously withCMEVT_A_COMPLETED attribute set.

[3796] 11.4. Special Events, Frames, Commands or Verbs

[3797] None.

[3798] 11.5. Properties

[3799] None.

[3800] 12. Encapsulated Interactions

[3801] DM_EPP is an assembly and does not have encapsulatedinteractions. Its subordinates, however, may have such depending ontheir implementation. For more information on the subordinates, pleaserefer to the data sheets of:

[3802] DM_BSP

[3803] DM_STX

[3804] DM_ASB

[3805] DM_EPP

[3806] DM_ACT

[3807] 13. Internal Definition

[3808]FIG. 123 illustrates the internal structure of the inventiveDM_EPP part.

[3809] 14. Theory of Operation

[3810] DM_EPP is an assembly. It is based on parts included in theAdvanced Part Library (APL). DM_EPP implements its functionality usingtwo Notifiers (DM_NFY) connected as shown on the diagram.

[3811] The notifiers are parameterized to issueEV_REQ_DISABLE/EV_REQ_ENABLE before (N_(fwd)) or after (N_(bck)) eventis received.

[3812] Each IRP event going in the forward direction causes N_(fwd) toissue EV_REQ_DISABLE before the event is forwarded out.

[3813] This in turn disables the input flow until a completion eventcomes through the back channel of out terminal. The completion eventwill cause N_(bck) to issue EV_REQ_ENABLE after it passes it back to in.

[3814] 15. Subordinate Parameterization Subordinate Property ValueN_(fwd) trigger_ev EV_REQ_IRP pre_ev EV_REQ_DISABLE N_(bck) trigger_evEV_REQ_IRP post_ev EV_REQ_DISABLE

[3815] 16. Use Cases

[3816] 16.1. IRP Event Comes In

[3817] The IRP event arrives at the in terminal, which is forwarded tothe splitter 1. Splitter1 forwards it to N_(fwd), which issuesEV_REQ_DISABLE before it passes the event out. EV_REQ_DISABLE isforwarded out through flw terminal, which in turn disables the inputflow.

[3818] N_(fwd) finally sends the event out, which passing throughsplitter 2 is sent out through the out terminal. At this point DM_EPPexpects that the event will be completed asynchronously and will waitfor a completion event to come through the back channel if out.

[3819] 16.2. Completion Event Comes In

[3820] When the completion event comes through the back channel of outterminal (even within the output operation to the out terminal),splitter 2 forwards it to N_(bck). N_(bck) first sends it out throughthe back channel of in terminal (passing splitter 1) and then issuesEV_REQ_ENABLE, which gets forwarded out through the flw terminal. Thislast action restores the state of the input event flow.

Property Space Suport Property Exposers DM_PEX—Property Exposer

[3821]FIG. 124 illustrates the boundary of the inventive DM_PEX part.

[3822] DM_PEX is a part that can be used to manipulate properties of theassembly it is included into. DM_PEX allows properties of the assemblyto be manipulated through its prop terminal, making it convenient.

[3823] DM_PEX does not have state. It redirects all the operations itimplements to the assembly that contains it.

[3824] 1. Boundary

[3825] 1.1. Terminals

[3826] Terminal “prop” with direction “In” and contract I_A_PROP. Note:Direct access to properties of the assembly by name. The entity id isnot used and must be 0.

[3827] 1.2. Events and Notifications

[3828] None.

[3829] 1.3. Special Events, Frames, Commands or Verbs

[3830] None.

[3831] 1.4. Properties

[3832] None.

[3833] 2. Encapsulated Interactions

[3834] None.

[3835] 3. Specification

[3836] 4. Responsibilities

[3837] 23. Implement interface for manipulation of assembly'sproperties.

[3838] 5. Theory of Operation

[3839] None.

[3840] 5.1. State Machine

[3841] None.

[3842] 5.2. Main Data Structures

[3843] None.

[3844] 5.3. Mechanisms

Accessing Properties of the Host Assembly

[3845] Most parts don't need to know the OID of their host assembly(host, or parent assembly is the assembly in which a given part iscreated as subordinate).

[3846] DM_PEX needs to operate on its host assembly. DM_PEX identifiesitself as part that has such need either by calling an API function orby placing a specific value in its part descriptor.

[3847] DM_PEX can access the properties of the host assembly by usingany mechanism. Two possible mechanisms are described below:

[3848] 1. DM_PEX can obtain the OID of its host assembly by calling anAPI function and then use the standard cm_prp_get and cm_prp_set, etc.,property API functions.

[3849] DM_PEX can obtain an internal, private interface to the hostassembly. That private interface provides at least the propertyoperations needed by DM_PEX.

Property Containers DM_VPC—Virtual Property Container

[3850]FIG. 125 illustrates the boundary of the inventive DM_VPC part.

[3851] DM_VPC is a property container that provides storage and standardproperty services for virtual (dynamic) properties.

[3852] DM_VPC implements all of the operations specified in the I_A_PROPinterface and imposes the restriction that there be only one openproperty query at a time.

[3853] DM_VPC provides support all of the standard DriverMagic propertytypes and has no self-imposed restriction as to the size of the propertyvalue, provided there is enough system memory.

[3854] 1. Boundary

[3855] 1.1. Terminals Name Dir Contract Notes fac In I_PRPFAC v-table,infinite cardinality, synchronous This terminal is used to create,destroy, and reinitialize virtual properties. prp In I_A_PROP v-table,infinite cardinality, synchronous This terminal is used to get, set,check and enumerate virtual properties in the container.

[3856] 1.2. Events and Notifications

[3857] None.

[3858] 1.3. Special Events, Frames, Commands or Verbs

[3859] None.

[3860] 1.4. Properties

[3861] Property “max_container_sz” of type “UINT32”. Note: Specifies themaximum number of properties to store in the container. Set to 0 toindicate no limit. Default: 64

[3862] 2. Encapsulated Interactions

[3863] None.

[3864] 3. Specification

[3865] 4. Responsibilities

[3866] 24. Maintain dynamic property container for virtual properties.

[3867] 25. Provide property factory services on the property container.

[3868] 26. Provide standard property operations for properties stored inthe property container.

[3869] 5. Theory of Operation

[3870] 5.1. Main Data Structures

Property Container

[3871] DM_VPC uses the ClassMagic handle manager services to implementits property container. With each handle, DM_VPC stores a pointer to avirtual property structure as context. Each virtual property structurecontains information about a particular property.

[3872] 5.2. Mechanisms

Creating and Destroying Properties

[3873] When DM_VPC receives a request to create a new property, it firstsearches the container to ensure that the property doesn't alreadyexist. DM_VPC then creates a virtual property structure for theproperty, creates a handle and stores a pointer to the structure as acontext.

[3874] When DM_VPC receives a request to destroy a single property, itfinds the property in the property container, frees the virtual propertystructure, and frees the handle. If the destroy operation specifies thatall properties are to be destroyed, DM_VPC enumerates the propertycontainer, freeing each virtual property structure and handle.

DM_REP—Hierarchical Repository

[3875]FIG. 126 illustrates the boundary of the inventive DM_REP part.

[3876] DM_REP is a hierarchical repository with notifications. Itimplements a hierarchical data storage in memory. The repositoryprovides functionality to store, query and retrieve data by hierarchical“data paths”. The data paths are strings of up to 256 characters, whichare constructed using identifiers and array indices (the terms used asdefined by the C programming language). Both identifiers and indices arereferred to as “pels”—short for “path element”.

[3877] Data paths are constructed using no more than 16 pels, i.e. thetotal number of identifiers and indices in a valid data path cannotexceed 16. Each data path corresponds to a piece of data (data element)with a variable size. This data can be stored and retrieved throughDM_REP terminals item and list.

[3878] DM_REP does not have a notion of data types; it supports variablesize binary data only. However, for each data element, DM_REP provides a32-bit external context that can be manipulated in parallel with thedata. This context is frequently used to store and retrieveidentification of the actual data type.

[3879] DM_REP supports queries on the data paths (query terminal). Thequery criteria are defined using query strings. DM_REP supports up to 16general queries simultaneously.

[3880] DM_REP supports serialization of the repository data to a binaryfile or the system registry (serialize terminal). It also supportsdeserialization from a binary file, system registry or INI file.

[3881] DM_REP also provides an interface for data path manipulation(dpath terminal). This allows data paths to be joined together or splitapart into “pels”.

[3882] DM_REP generates notifications when a data item is changed, addedor deleted. All notifications are sent out through the nfy terminal. Thenotifications are sent with an event that describes which data path wasaffected.

[3883] This part is available only in Win32 User Mode environment.

[3884] 6. Boundary

[3885] 6.1. Terminals

[3886] Terminal “item” with direction “In” and contract I_ITEM. Note:v-table, infinite cardinality, active-time, synchronous. Repository dataitem manipulation.

[3887] Terminal “list” with direction “In” and contract I_LIST. Note:v-table, infinite cardinality, active-time, synchronous. Repository datalist manipulation.

[3888] Terminal “query” with direction “In” and contract I_QUERY. Note:v-table, infinite cardinality, active-time, synchronous. Repository pathqueries.

[3889] Terminal “serialize” with direction “In,” and contract I_SERIAL.Note: v-table, infinite cardinality, active-time, synchronous.Repository serialization.

[3890] Terminal “dpath” with direction “In” and contract I_DPATH. Note:v-table, infinite cardinality, active-time, synchronous. Repository pathmanipulation.

[3891] Terminal “nfy” with direction “Out” and contract I_DRAIN. Note:v-table, cardinality 1, floating, synchronous. All notifications fromthe repository are sent out through this terminal.

[3892] 6.2. Events and Notifications

[3893] No incoming events. Outgoing Event Bus NotesEV_REP_NFY_DATA_CHANGE EV_REP This event is sent out through the nfyterminal when a data item is changed, added, or deleted.

[3894] 6.3. Special Events, Frames, Commands or Verbs

[3895] None.

[3896] 6.4. Properties

[3897] None.

[3898] 7. Encapsulated Interactions

[3899] None.

[3900] 8. Specification

[3901] 9. Responsibilities

[3902] 1. Provide functionality for data storage and retrieval throughitem and list terminals.

[3903] 2. Provide functionality for queries on the data path namespace.

[3904] 3. Provide functionality for serialization of the repository to afile or the registry.

[3905] 4. Provide functionality for deserialization of the repositoryfrom a file, registry, or INI file.

[3906] 5. Provide functionality for data path manipulation.

[3907] 6. Generate notifications through the nfy terminal when a dataitem is changed, added, or deleted.

[3908] 10. Theory of Operation

[3909] 10.1. Data Path Syntax

[3910] The data path syntax is very similar to the syntax for specifyingdata structures in programming languages like C. Here are a few examplesof typical data paths:

[3911] customer[1].name

[3912] Sensor.Value

[3913] matrix[1][2][3]

[3914] 10.2. INI File Structure (Deserialization)

[3915] Here is the INI file structure expected on deserialization of therepository:

[3916] <data path>=<context>[: {<data>|<fileref>}]

[3917] The expression on the right side of the equal sign can becontinued on a new line by placing backslash (\) on the incomplete line(like in C preprocessor).

[3918] Here are somewhat informal definitions of the items above: <data>:: = <datum> [, <data>] <datum> :: = {[−]<number>[L|S|B] | “<text>” |′text′} <fileref> :: = @<filename> <context> :: = <number> <number> :: =<dec> | 0x<hex> | 0<oct>

[3919] Here is an example of an INI file demonstrating the syntax:

[3920] [rep_data]

[3921] image.name=1: “Sample”

[3922] image.author=2: ‘John Doe’

[3923] image.size.x=3: 640

[3924] image.size.y=4: 480

[3925] cast[0]=5: @c:\external.dat

[3926] cast[0].alias=6: “Conan”

[3927] cast[0].type=0×7f: ‘Barbarian’

[3928] cast[0].data=1: −2S, 24L, 255B, ‘a text’, \

[3929] “More text”

[3930] Here are the possible data types for numbers. If type is notexplicitly specified with a suffix, the repository automatically assignsthe smallest data type in which the value fits. Supported numbersuffixes:

[3931] S=Short (16 bit)

[3932] L=Long (32 bit)

[3933] B=Byte (8 bit)

[3934] The difference between strings with single quotes and stringswith double quotes is that for double-quoted strings, the repositoryautomatically includes a 0 to terminate the string. Single-quotedstrings are stored as is, with the exact length and no terminator. Toillustrate, the following two paths will contains the same values, of 5bytes each:

[3935] customer[0].name=1: “Name”

[3936] customer[1].name=1: ‘Name’, 0

[3937] Finally, the <context> value in front of the colon sign is thevalue that will be associated with the data item. It can be obtainedtogether with the item, using the I_ITEM interface.

[3938] 10.3. Binary File Structure

[3939] The following is the binary structure of the DM_REP serializedimage:

[3940] The header and footer signatures are as follows:

[3941] Header: Object Repository Data Format Version 2.0\r\n\x1a

[3942] Footer: \r\n[end]\r\n\x1a

[3943] 10.4. Mechanisms

Data Storage/retrieval Through I_ITEM Interface

[3944] Through the item terminal, single data paths are retrieved, setand deleted from the repository. The operations supported by item areget, set and remove.

[3945] The get operation retrieves the current value of the data path.The set operation sets the value of a data path. If the data pathdoesn't exist in the repository when setting data, it is created. Theremove operation deletes the data item from the repository.

[3946] The data path is either absolute or relative to a current item ina specified query.

[3947] All changes generate notifications through nfy.

Data Storage/retrieval Through I_LIST Interface

[3948] Through the list terminal, elements of data arrays are added toand removed from the repository. The operations supported are add andremove.

[3949] DM_REP maintains arrays of data paths. The array consists of oneor more data path names and indexes (e.g., customer[1],customer[1].name, customer1].phone[0], etc.) When adding a new elementto the array, the caller specifies only the base name (e.g., customer orcustomer[1].phone). DM_REP chooses the next available index for the datapath. The data path is constructed by DM_REP and returned to the callerfor later reference.

[3950] It is possible for a data array to have missing elements. When anelement is deleted, it is marked as available. Eventually throughaddition of new elements, the previously deleted elements are reused.

[3951] The index range supported by the repository is 0 to 16383.

[3952] The data path is either absolute or relative to a current item ina specified query.

[3953] All changes to a data path or its value will generate a datachange notification through nfy. Unlike I_ITEM, when a data array itemis removed, any items that are within its subtree are also removed.

Queries on the Data Path Namespace

[3954] DM_REP provides a way to query the data path namespace of therepository. The data path namespace consists of all the existing datapaths in the repository (single items and arrays).

[3955] DM_REP supports up to 16 data path queries simultaneously. Thequery criteria is defined with query strings constructed by thefollowing rules:

[3956] 1. Single question mark can replace a single path element (e.g.“a.?.b”)

[3957] 2. Asterisk can replace zero or more path elements (e.g. “a.*”)

[3958] 3. There cannot be more than one asterisk in the query string(e.g. “*.*” is wrong)

[3959] 4. Asterisk must be the last path element (e.g. “*.?”, “a.*.b”are wrong)

[3960] The query terminal is used to execute queries on the data pathnamespace. A query must first be opened using the open operation. DM_REPsupports a full set of query operations including get_first, get_next,get_prev, get_last, and get_curr.

Serialization/deserialization of the Repository

[3961] DM_REP allows serialization of the repository to a binary file orthe system registry. DM_REP allows deserialization of the repositoryfrom a binary file, system registry or an INI file.

Data item Notifications

[3962] DM_REP will generate events which are notifications that a dataitem was changed, added or deleted. This notification is calledEV_REP_NFY_DATA_CHANGE. This notification is sent out of the nfyterminal.

[3963] The notification describes which data path was affected.Notifications are issued when a data path value is changed, or a datapath is added or deleted to/from the repository.

[3964] The event that comes out through nfy can be distributed eithersynchronously or asynchronously. The event is self-owned andself-contained. Note that recipients of the event may need to free it;see I_DRAIN and CM_EVENT_HDR for details.

[3965] 10.5. Use Cases

Working With the Repository

[3966] 1. A new repository is created or is loaded from secondarystorage using DM_REP's serialize terminal.

[3967] 2. The user adds/deletes data items or data item arrays usingDM_REP's item and list terminals.

[3968] 3. The repository may be saved to secondary storage usingDM_REP's serialize terminal.

Querying the Repository

[3969] 1. A new repository is created or is loaded from secondarystorage using DM_REP's serialize terminal.

[3970] 2. The user adds/deletes data items or data item arrays usingDM_REP's item and list terminals.

[3971] 3. The user opens a new query on the repository.

[3972] 4. The data items are enumerated using DM_REP's query terminal(get_first, get_next, get_last, get_prev, get_curr). The data itemsmatching the query are returned by the operations.

[3973] 5. The user closes the query on the repository.

[3974] 6. The repository may be saved to secondary storage usingDM_REP's serialize terminal.

Receiving Repository Notifications

[3975] 1. A new repository is created or is loaded from secondarystorage using DM_REP's serialize terminal.

[3976] 2. The user adds/deletes data items or data item arrays usingDM_REP's item and list terminals.

[3977] 3. For each change made in the previous step, the repositorysends an EV_REP_NFY_DATA_CHANGE notification sent out through its nfyterminal (if connected), along with an event data describing the eventand which data path was affected.

[3978] The recipient may check the data path and perform any operationsit needs; at the end it frees the event (if the CMEVT_A_SELF_OWNEDattribute is set). See EV_REP for details on the notification data.

Parameterizers DM_PRM—Parameterizer (From Registry)

[3979]FIG. 128 illustrates the boundary of the inventive DM_PRM part.

[3980] DM_PRM is a generic Registry-based parameterizer. This part canbe used for parameterizing part instances in part arrays.

[3981] This part is available only in Windows NT/95/98 Kernel Modeenvironments.

[3982] Deserialization of the properties from the registry is triggeredwhen the property with a particular name (specified by the reg prop nameproperty on DM_PRM) is set through terminal i_prp. The “trigger”property is expected to be of type CM_PRP_T_UNICODEZ for Windows NT andCM_PRP_T_ASCIZ for Windows 95/98 Kernel Modes. The value of the“trigger” property is the actual path from which the deserialization isperformed.

[3983] All other property operations on the i prp input are passedunchanged to o_prp. This allows DM_PRM to be inserted between two partsconnected through an I_A_PROP interface. DM_PRM transparently passes alloperations on its i_fac input to o_fac as well.

[3984] The event that triggers DM_PRM to begin serialization is asuccessful deactivation of a part performed through o_fac terminal. Onthis event DM_PRM updates the registry.

[3985] 1. Boundary

[3986] 1.1. Terminals

[3987] Terminal “i_prp” with direction “In” and contract I_A_PROP. Note:Input part array property interface. All operations are passedtransparently to o_prp.

[3988] Terminal “o_prp” with direction “Out” and contract I_A_PROP.Note: All property operations on the i_prp input are passedtransparently to this output.

[3989] Terminal “i_fac” with direction “In” and contract I_A_FACT. Note:Input part array factory interface. All operations are passedtransparently to o_fac.

[3990] Terminal “o_fac” with direction “Out” and contract I_A_FACT.Note: Calls to i_fac are passed to this output. DM_PRM assumes that thearray that is connected to this output is the same as the one connectedto the o_prp output. This output may remain unconnected if i_facterminal is not connected (floating).

[3991] 1.2. Events and Notifications

[3992] None.

[3993] 1.3. Special Events, Frames, Commands or Verbs

[3994] None.

[3995] 1.4. Properties

[3996] Property “reg_prop_name” of type “ASCIZ”. Note: Name of propertyto monitor on i_prp.set operations. The default value is “reg_root”

[3997] Property “reg_hive” of type “UINT32”. Note: A registry key to useas the root for all registry operations. The default value is NULL(absolute) for Windows NT and HKEY_LOCAL_MACHINE for Windows 95/98Kernel Mode environments.

[3998] Property “enforce_out_prop” of type “UINT32”. Note: Ensure thatthe o_prp.set operation on the property specified by reg_prop_name issuccessful. The default value is FALSE.

[3999] Property “reg_path_suffix” of type “UNICODE”. Note: Sub-path tobe added to value set on reg_prop_name when reading/setting values inthe registry. This value is also removed from the property value when ai_prp.get operation is invoked for the property specified byreg_prop_name. The default value is “ ”.

[4000] Property “serialize” of type “UINT32”. Note: Serialize propertieswhen I_A_FACT.deactivate received. The default value is FALSE.

[4001] Property “ser_query” of type “ASCIZ”. Note: Query string to usewhen serializing properties. The default value is “*”.

[4002] Property “ser_attr_mask” of type “UINT32”. Note: Attribute maskto use when performing query operation to serialize properties. Thedefault value is CM_PRP_A_PERSIST.

[4003] Property “ser_attr_val” of type “UINT32”. Note: Attribute valueto use when performing query operation to serialize properties. Thedefault value is CM_PRP_A_PERSIST.

[4004] Property “ser_existing_only” of type “UINT32”. Note: Serializeonly those properties that already exist in the registry. The defaultvalue is FALSE.

[4005] Property “buf_sz” of type “UINT32”. Note: Initial size [in bytes]of buffer to allocate for reading values from the registry. The defaultvalue is 512 bytes. This value is treated as a lower limit—DM_PRM mayround it up and allocate more memory if the given value is too small.

[4006] Property “buf_realloc” of type “UINT32”. Note: Reallocate bufferif it becomes too small. The default value is TRUE.

[4007] 2. Encapsulated Interactions

[4008] DM_PRM uses the Windows NT/95/98 Kernel Mode Registry API.

[4009] 3. Specification

[4010] 4. Responsibilities

[4011] 1. Deserialize properties when the property specified byreg_prop_name is set through DM_PRM's i_prp input.

[4012] 2. Serialize properties after a successful o_fac.deactivate callif serialization is enabled.

[4013] 3. Map or convert between registry data types and ClassMagicproperty value types.

[4014] 4. Pass all operations from i_prp to o_prp.

[4015] 5. Pass all operations from i_fac to o_fac.

[4016] 5. Theory of Operation

[4017] 5.1. State Machine

[4018] None.

[4019] 5.2. Main Data Structures

[4020] None.

[4021] 5.3. Mechanisms

Deserialization of Properties

[4022] When DM_PRM receives a call on its i_prp.set operation, it checksif the property being set matches the name specified by itsreg_prop_name property. If the property matches, DM_PRM forms a registrypath from the property value and its reg_path_suffix property. DM_PRMopens the registry key; enumerates its values, and for each value found,validates that the property types are compatible between ClassMagic andthe registry, and invokes its o_prp.set output if the types arecompatible. If the property types are not compatible, DM_PRM logs anerror message and does not set the property. When all values have beenenumerated, DM_PRM then forwards the original i_prp.set operation withthe added suffix, to its o_prp output.

[4023] The following table describes the valid ClassMagic property typefor each registry type in Windows NT Kernel Mode environment: ValidClassMagic Property Registry Type type(s) REG_DWORD or CMPRP_T_UINT32 orREG_DWORD_LITTLE_ENDIAN CMPRP_T_SINT32 REG_SZ or CMPRP_T_ASCIZ orREG_EXPAND_SZ CMPRP_T_UNICODEZ REG_DWORD_BIG_ENDIAN CMPRP_T_BINARYREG_BINARY CMPRP_T_MBCSZ, CMPRP_T_BINARY, CMPRP_T_UCHAR REG_MULTI_SZ,CMPRP_T_BINARY REG_LINK, or REG_RESOURCE_LIST

[4024] The same for Windows 95/98 Kernel Mode environment: ValidClassMagic Property Registry Type type(s) REG_DWORD or CMPRP_T_UINT32 orREG_DWORD_LITTLE_ENDIAN CMPRP_T_SINT32 REG_SZ or REG_EXPAND_SZCMPRP_T_ASCIZ REG_DWORD_BIG_ENDIAN CMPRP_T_BINARY REG_BINARYCMPRP_T_UNICODEZ, CMPRP_T_MBCSZ, CMPRP_T_BINARY, CMPRP_T_UCHARREG_MULTI_SZ, REG_LINK, CMPRP_T_BINARY or REG_RESOURCE_LIST

Serialization of Properties

[4025] When DM_PRM receives a call on its i fac.deactivate operation, itfirst forwards the call out its o_fac output. If the call is successfuland DM_PRM's serialize property has been set to TRUE, DM_PRM callso_prp.get with its reg_prop_name property to retrieve the Registry paththat was set. It then opens the Registry key and opens a query on itso_prp output based upon its ser_query, ser_attr_mask, and ser_attr_valproperties.

[4026] For each property that is returned, DM_PRM first validates thatthe types are compatible between ClassMagic and the Registry. If thetypes are compatible, DM_PRM saves the value in the registry using thecurrent registry type. If the types are not compatible, DM_PRM logs anerror message, and saves the value in the registry with a preferred typebased upon the property value. The table below describes the validregistry types, and the preferred registry type for each ClassMagictype. If the property does not currently exist in the registry, DM_PRMsaves the value with the preferred registry type.

[4027] If DM_PRM's ser_existing_only property is set to TRUE, DM_PRMwill save only those properties that currently exist in the Registry.The mapping between property types is described in the following tables.

[4028] For Windows NT Kernel Mode environment: ClassMagic Valid RegistryPreferred Type Types Registry Type CMPRP_T_UNIT32 REG_DWORD_or REG_DWORDor REG_DWORD_LITTLE_(—) CMPRP_T_SINT32 ENDIAN CMPRP_T_ASCIZ REG_SZ orREG_SZ or REG_EXPAND_SZ CMPRP_T_(—) UNICODEZ CMPRP_T_UCHAR REG_BINARYREG_BINARY or CMPRP_T_MBCSZ CMPRP_T_BINARY REG_BINARY, REG_BINARYREG_DWORD_BIG_(—) ENDIAN, REG_LINK, REG_RESOURCE_LIST, or REG_MULTI_SZ

[4029] For Windows 95/98 Kernel Mode environment: ClassMagic ValidRegistry Preferred Type Types Registry Type CMPRP_T_UNIT32 REG_DWORD_orREG_DWORD or REG_DWORD_LITTLE_(—) CMPRP_T_SINT32 ENDIAN CMPRP_T_ASCIZREG_SZ or REG_SZ REG_EXPAND_SZ CMPRP_T_UCHAR, REG_BINARY REG_BINARYCMPRP_T_(—) UNICODEZ, or CMPRP_T_MBCSZ CMPRP_T_BINARY REG_BINARY,REG_BINARY REG_DWORD_BIG_(—) ENDIAN, REG_LINK, REG_RESOURCE_LIST, orREG_MULTI_SZ

[4030] DM_PRM transparently passes all other calls on its i_fac input toits o_fac output.

Buffer Allocation and Reallocation

[4031] DM_PRM allocates a data buffer upon activation to be used forretrieving property values from the registry or from a part. If any ofthe operations return ERROR_INSUFFIENT_BUFFER (registry API) orCMST_OVERFLOW (ClassMagic), DM_PRM will reallocate the buffer to theneeded size as returned by the operation. DM_PRM frees the buffer whenit is deactivated.

Handling other Property Operations (get, chk)

[4032] When DM_PRM receives a call on i_prp.chk, and the property namematches its reg_prop_name, DM_PRM appends the value of itsreg_path_suffix property to the incoming value before forwarding theoperation.

[4033] When DM_PRM receives a call on i_prp.get, and the property namematches its reg_prop_name, DM_PRM forwards the call to its o_prp outputand upon a successful return, strips the reg_path_suffix from the valuebefore returning from the call.

[4034] All other operations on DM_PRM's i_prp input are passedtransparently to DM_PRM's o_prp output.

Serializers DM_SER—Serializer (to registry)

[4035]FIG. 129 illustrates the boundary of the inventive DM_SER part.

[4036] DM_SER is used to serialize a part's internal state (properties)to the system registry.

[4037] When DM_SER receives a specific event from the in terminal(specified through a property), DM_SER enumerates all the properties ofthe part connected to the prp terminal and saves them to the registry.The serialization event received from in is also passed through the outterminal.

[4038] DM_SER may be parameterized to serialize a part before or afterthe completion of the serialization event passed through out.

[4039] The events sent through out can be completed either synchronouslyor asynchronously—DM_SER takes care of the proper completion andnecessary cleanup.

[4040] Unrecognized events received on in or aux are passed out throughthe opposite terminal without modification. This enables DM_SER to beinserted in any event flow and provides greater flexibility.

[4041] This part is available only in Windows NT and Windows 95/98Kernel Mode environments.

[4042] 1. Boundary

[4043] 1.1. Terminals

[4044] Terminal “in” with direction “Plug” and contract I_DRAIN. Note:Synchronous, v-table, cardinality 1 This teminal receives the(ev_serialize) event that serializes the part connected to the prpterminal. This event is also passed through the out terminal. Allunrecognized events received from this terminal are passed out throughaux without modification.

[4045] Terminal “out” with direction “Plug” and contract I_DRAIN. Note:Synchronous, v-table, cardinality 1 DM_SER passes the serializationevent (ev_serialize) through this terminal.

[4046] Terminal “prp” with direction “Out” and contract I_A_PROP. Note:Synchronous, v-table, cardinality 1 Serialization terminal. DM_SER usesthis terminal to enumerate the properties of a part in order toserialize its state to the registry.

[4047] Terminal “aux” with direction “Plug” and contract I_DRAIN. Note:Synchronous, v-table, cardinality 1, floating Auxiliary terminal. Allevents received from this terminal are passed through in withoutmodification. All unrecognized events received from in are passed outthrough aux without modification.

[4048] 1.2. Events and Notifications

[4049] The following events are recognized on the in terminal: IncomingEvent Bus Notes (ev_serialize) CMEVENT_HDR This event triggers DM_SER toserialize the state of the part connected to the prp terminal.

[4050] The following events are recognized on the out terminal: OutgoingEvent Bus Notes (ev_serialize) CMEVENT_HDR This event is passed throughthe out terminal when received on the in terminal. The order betweensending this event and serialization is determined by the ser_discproperty. This event may be processed synchronously or asynchronously.(ev_cleanup) CMEVENT_HDR This is the cleanup event that is sent throughthe out terminal if serialization fails. This event may be processedsynchronously or asynchronously.

[4051] 1.3. Special Events, Frames, Commands or Verbs

[4052] None.

[4053] 5 1.4. Properties

[4054] Property “ev_serialize” of type “UINT32”. Note: Event ID of theserialization event received on the in terminal. When this event isreceived on in, DM_SER serializes the state of the part connected to theprp terminal. If EV_NULL, DM_SER passes all events received on the interminal out through the aux terminal. Default is EV_NULL.

[4055] Property “ev_cleanup” of type “UINT32”. Note: Event ID of thecleanup event sent through the out terminal if the serialization fails.If EV_NULL, no cleanup event is sent through the out terminal. Defaultis EV_NULL.

[4056] Property “ser_disc” of type “ASCIZ”. Note: Distribution of theserialization event. Can be one of the following values: fwd_ignore—sendserialization event through out first then serialize part's state.bwd_ignore—serialize part's state first then send serialization eventthrough out. fwd_cleanup—send serialization event through out first thenserialize part's state. If serialization fails, send cleanup eventthrough out. See the Mechanism section for more information. Default isfwd_ignore.

[4057] Property “async_cplt_attr” of type “UINT32”. Note: Value of theattribute that signifies that the serialization event received from incan be processed asynchronously. The default is: CMEVT_A_ASYNC_CPLT

[4058] Property “cplt_attr” of type “UINT32”. Note: Value of theattribute that signifies that the processing of the serialization eventpassed through the out terminal has been completed. When theserialization event passed through out is processed asynchronously, thecompletion event passed back to DM_SER is expected to have thisattribute set. The default is: CMEVT A COMPLETED

[4059] Property “cplt_s_offs” of type “UINT32”. Note: Offset incompletion event bus for the completion status. The size of the storagemust be at least sizeof (cmstat). Default is 0×0C. (first field in eventbus after standard fields id, sz and attr)

[4060] Property “reg_prop_name” of type “ASCIZ”. Note: Name of theproperty that contains the registry path used to serialize a partsstate. This property is expected to be of type UNICODE. Beforeserialization, DM_SER reads the value of this property (prp.get) anduses the value as the location to store the parts state in the registry.Default is “reg_root”.

[4061] Property “reg_hive” of type “UINT32”. Note: A registry key to useas the root for registry serialization operations. The default value isNULL (absolute) for Windows NT/WDM and HKEY_LOCAL_MACHINE for Windows95/98 (VxD) Kernel Mode environments.

[4062] Property “sera_attr_mask” of type “UINT32”. Note: Attribute maskto use when performing query operations to serialize properties. Defaultis CMPRP_A_PERSIST.

[4063] Property “sera_attr_value” of type “UINT32”. Note: Attributevalue to use when performing query operations to serialize properties.Default is CMPRP A PERSIST.

[4064] Property “ser_existing_only” of type “UINT32”. Note: TRUE toserialize only those properties that already exist in the registry.Default is FALSE.

[4065] Property “buf_sz” of type “UINT32”. Note: Initial size [in bytes]of buffer to allocate for reading property values from the partconnected to the prp terminal. This value is treated as a lower limit.DM_SER may round it up and allocate more memory if the given value istoo small. Default is 512 bytes.

[4066] Property “buf_realloc” of type “UINT32”. Note: TRUE to reallocateproperty value buffer if it becomes too small. Default is TRUE.

[4067] 2. Encapsulated Interactions

[4068] DM_PRM uses the Windows 95/98 and Windows NT Registry API(kernel-mode).

[4069] 3. Internal Definition

[4070]FIG. 130 illustrates the internal structure of the inventiveDM_SER part.

[4071] 4. Subordinate's Responsibilities

[4072] 4.1. SEQ—Event Sequencer

[4073] Distribute incoming events received on in to the parts connectedto the out1 and out2 terminals.

[4074] Allow both synchronous and asynchronous completion of thedistributed events.

[4075] Pass all unrecognized events received on the in terminal throughthe aux terminal.

[4076] Pass all events received on the aux terminal through the interminal.

[4077] 4.2. BSP—Bi-directional Splitter

[4078] Provide plumbing to enable connection of a bidirectional terminalto an unidirectional input or output.

[4079] 4.3. ADP—Activation/Deactivation Adapter

[4080] Convert deactivation events received on the evt terminal intofac.deactivate operation calls.

[4081] 4.4. PRM—Parameterizer

[4082] Serialize properties to the registry on a i_fac.deactivateoperation call.

[4083] Map or convert between registry data types and ClassMagicproperty types.

[4084] 4.5. UST—Universal Stopper

[4085] Stub all operations invoked through the in terminal and returnCMST_OK.

[4086] 5. Distribution of Properties Property Distr. Subordinateev_serialize Group seq.ev[0].ev_id ev_serialize Group adp.ev_deactivateev_cleanup Redirected seq.ev[0].cleanup_id ser_disc Redirectedseq.ev[0].disc async_cplt_attr Redirected seq.async_cplt_attr cplt_attrRedirected seq.cplt_attr cplt_s_offs Redirected seq.cplt_s_offsreg_prop_name Redirected prm.reg_prop_name reg_hive Redirectedprm.reg_hive ser_attr_mask Redirected prm.ser_attr_mask ser_attr_valRedirected prm.ser_attr_val ser_existing_only Redirectedprm.ser_existing_only buf_sz Redirected prm.buf_sz buf_reallocRedirected prm.buf_realloc

[4087] 6.

[4088] 7. Subordinate Parameterization Part Property Value adp pid_ofs−1 prm serialize TRUE ust in_is_drain FALSE ust ret_s CMST_OK

[4089] 8. Theory of Operation

[4090] 8.1. Mechanisms

Serialization Event Distribution

[4091] DM_SER serializes a parts state when it receives an ev_serializeevent from the in terminal. The disciplines defined below are used todetermine whether this serialization event is passed through the outterminal before or after the actual part serialization. They alsodetermine whether serialization errors are considered and if a cleanupevent should be sent through the out terminal.

[4092] The serialization disciplines defined below are specified throughthe ser_disc property (ASCII strings):

[4093] fwd_ignore: The serialization event is passed through the outterminal before DM SER serializes the part connected to the prpterminal. All errors are ignored.

[4094] bwd_ignore: The serialization event is passed through the outterminal after DM_SER serializes the part connected to the prp terminal.All errors are ignored.

[4095] fwd_cleanup: Same as fwd_ignore except if the part serializationfails, DM_SER sends the cleanup event ev_cleanup through the outterminal.

[4096] The serialization failure status is propagated back to theoriginal caller.

Serialization of Properties

[4097] When DM_SER receives an ev_serialize event from the in terminal,it first calls o_prp.get with its reg_prop_name property to retrieve theregistry path of where to store the parts properties in the registry. Itthen opens the registry key and opens a query on its prp output basedupon its sera_attr_mask and ser_attr_val properties. DM_SER thenenumerates all the properties of the part connected to the prp terminal.

[4098] If the property does not currently exist in the registry, DM_SERsaves the value with the preferred registry type. If the property doesexist in the registry, DM_SER first validates that the types arecompatible between ClassMagic and the registry. If the types arecompatible, DM_SER saves the value in the registry using the registrytype. If the types are not compatible, DM_SER logs an error message, andsaves the value in the registry with a preferred type based upon theproperty value. The table below describes the valid registry types, andthe preferred registry type for each ClassMagic type.

[4099] If DM_SER's ser existing_only property is set to TRUE, DM_SERwill save only those properties that currently exist in the registry.

[4100] For Windows NT Kernel Mode/WDM environments: Preferred RegistryClassMagic Type Valid Registry Types Type CMPRP_T_(—) REG_DWORD orREG_(—) UINT32 or REG_DWORD_LITTLE_(—) DWORD CMPRP_T_(—) ENDIAN SINT32CMPRP_T_ASCIZ REG_SZ or REG_SZ or REG_EXPAND_SZ CMPRP_T_(—) UNICODEZCMPRP_T_(—) REG_BINARY REG_(—) UCHAR or BINARY CMPRP_T_(—) MBCSZCMPRP_T_(—) REG_BINARY, REG_(—) BINARY REG_DWORD_BIG_END BINARY IAN, REGLINK, REG_RESOURCE_LIST, or REG_MULTI_SZ

[4101] For Windows 95/98 VxD Kernel Mode environments: PreferredRegistry ClassMagic Type Valid Registry Types Type CMPRP_T_(—) REG_DWORDor REG_(—) UINT32 or REG_DWORD_LITTLE_(—) DWORD CMPRP_T_ ENDIAN SINT32CMPRP_T_ASCIZ REGSZ or REG_SZ REG_EXPAND_SZ CMPRP_T_UCHAR REG_BINARYREG_(—) BINARY CMPRP_T_(—) UNICODEZ, or CMPRP_T_(—) MBCSZ CMPRP_T_(—)REG_BINARY, REG_(—) BINARY REG_DWORD_BIG_END BINARY IAN, REG LINK,REG_RESOURCE_LIST, or REG_MULTI_SZ

Buffer Allocation and Reallocation

[4102] DM_SER allocates a data buffer upon activation to be used forretrieving property values from the registry or from a part. If any ofthe operations return ERROR_INSUFFIENT_BUFFER (registry API) orCMST_OVERFLOW (ClassMagic), DM_SER reallocates the buffer to the neededsize as returned by the operation. DM_SER frees the buffer when it isdeactivated.

DM_SERADP—Activation/Deactivation Adaptor

[4103]FIG. 131 illustrates the boundary of the inventive DM_SERADP part.

[4104] DM_SERADP is an adaptor that converts specific events received onthe evt terminal into fac.activate and fac.deactivate operation calls.

[4105] The activation and deactivation event IDs are specified asproperties on DM_SERADP. These events are always processedsynchronously.

[4106] DM_SERADP extracts the part ID that identifies the part to beactivated/deactivated from the bus that comes with the event. The offsetof the part ID storage is specified through a property.

[4107] DM_SERADP consumes all unrecognized events and returns CMST_OK.

[4108] 9. Boundary

[4109] 9.1. Terminals

[4110] Terminal “evt” with direction “In” and contract I_DRAIN. Note:Synchronous, v-table, infinite cardinality This terminal receives the(ev_activate) and (ev_deactivate) events which are converted intoI_A_FACT activate and deactivate operations (sent out through the facterminal). This terminal is ungaurded.

[4111] Terminal “fac” with direction “Out” and contract I_A_FACT. Note:Synchronous, v-table, cardinality 1 DM_SERADP invokes the life-cycleoperations activate and deactivate through this terminal when itreceives the (ev_activate) and (ev_deactivate) events from the evtterminal respectively.

[4112] 9.2. Events and Notifications Incoming Event Bus Notes(ev_activate) CMEVENT_(—) Activate part. HDR This event is convertedinto a activate operation call through the fac terminal. This event isalways processed synchronously. (ev_deactivate) CMEVENT_(—) Deactivatepart. HDR This event is converted into a deactivate operation callthrough the fac terminal. This event is always processed synchronously.

[4113] 9.3.

[4114] 9.4. Special Events, Frames, Commands or Verbs

[4115] None.

[4116] 9.5. Properties

[4117] Property “ev_activate” of type “UINT32”. Note: ID of the eventthat is converted into a activate operation call through the facterminal. If EV_NULL, DM_SERADP does not convert any events received onevt into fac.activate operation calls. In this case DM_SERADP consumesthe event and returns CMST_OK. Default is EV_NULL.

[4118] Property “ev_deactivate” of type “UINT32”. Note: ID of the eventthat is converted into a deactivate operation call through the facterminal. If EV_NULL, DM_SERADP does not convert any events received onevt into fac.deactivate operation calls. In this case DM_SERADP consumesthe event and returns CMST_OK. Default is EV_NULL.

[4119] Property “pid_ofs” of type “UINT32”. Note: Offset of the part IDin the event bus (specified in bytes). This ID identifies the part thatneeds to be activated or deactivated. DM_SERADP extracts the part IDfrom the event bus and passes it to the activate/deactivate operation onthe fac terminal. The size of the part ID storage is expected to be sizeof (DWORD). If −1, DM_SERADP passes NO_CMOID for the part ID. Default is0×0C (first field after the common event bus fields: sz, id and attr).

[4120] 10. Encapsulated Interactions

[4121] None.

[4122] 11. Specification

[4123] 12. Responsibilities

[4124] 1. Convert the (ev_activate) event (received on the evt terminal)into a fac.activate operation call. Extract the part ID from the eventbus and pass it with the call.

[4125] 2. Convert the (ev_deactivate) event (received on the evtterminal) into a fac.deactivate operation call. Extract the part ID fromthe event bus and pass it with the call.

[4126] 3. Consume all unrecognized events received on the evt terminaland return CMST_OK.

[4127] 13. Theory of operation

[4128] 13.1. Main data structures

[4129] None.

[4130] 13.2. Mechanisms

Event to Life-cycle Conversion

[4131] DM_SERADP converts the (ev_activate) and (ev_deactivate) eventsreceived on the evt terminal into fac.activate and fac.deactivateoperation calls respectively.

[4132] Before invoking the operation, DM_SERADP uses the pid_ofsproperty to extract the part ID from the event bus. This ID is passed asan argument to the operation call—it identifies the part instance thatshould be activated or deactivated.

[4133] The return status of the part activation/deactivation ispropagated back to the caller.

Property Interface Adaptors DM_E2P Event to Property Interface Converter

[4134]FIG. 132 illustrates the boundary of the inventive DM_E2P part.

[4135] DM_E2P converts EV_PRP_REQ events received on the evt terminalinto operations of the I_A_PROP interface and executes the operationsynchronously. It is assumed that EV_PRP_REQ can carry any operation ofthe property interface and that its bus is self-contained with possiblyvariable size, with the actual data value being the last field in theevent bus. Please see E_PROP.H for a detailed description of theEV_PRP_REQ event.

[4136] 1. Boundary

[4137] 1.1. Terminals

[4138] Terminal “evt” with direction “In” and contract I_DRAIN. Note:Process EV_PRP_REQ events. This terminal is ungaurded.

[4139] Terminal “prp” with direction “Out” and contract I_A_PROP. Note:Request property operations. EV_PRP_REQ events received from the evtterminal are translated into property operations invoked through thisterminal.

[4140] 1.2. Events and Notifications Incoming Event Bus Notes EV_PRP_REQB_EV_PRP Request property operation.

[4141] 1.3. Special Events, Frames, Commands or Verbs

[4142] None.

[4143] 1.4. Properties

[4144] 5 None.

[4145] 2. Encapsulated Interactions

[4146] None.

[4147] 3. Specification

[4148] 4. Responsibilities

[4149] 1. Synchronously process EV_PRP_REQ events by translating theminto I_A_PROP operations and invoking the operation out prp.

[4150] 2. Refuse all other events.

[4151] 3. Fill in the completion status of the event bus when theI_A_PROP operation returns.

[4152] 5. Theory of Operation

[4153] 5.1. State Machine

[4154] None.

[4155] 5.2. Main Data Structures

[4156] None.

[4157] 5.3. Mechanisms

Translation of EV_PRP_REQ into I_A_PROP Operations

[4158] When DM_E2P receives an EV_PRP_REQ event, it determines theI_A_PROP operation to call based on the opcode field of the B_EV_PRPbus. The translation is as follows:

[4159] PROP_OP_GET→get

[4160] PROP_OP_SET→set

[4161] PROP_OP_CHK→chk

[4162] PROP_OP_GET_INFO→get_info

[4163] PROP_OP_QRY_OPEN→qry_open

[4164] PROP_OP_QRY_CLOSE→qry_close

[4165] PROP_OP_QRY_FIRST→qry_first

[4166] PROP_OP_QRY_NEXT→qry_next

[4167] PROP_OP_QRY_CURR→qry_curr

[4168] DM_E2P uses the fields of the incoming B_EV_PRP bus to fill inthe fields for the B_A_PROP bus without modification and makes the call.When the I_A_PROP operation returns, DM_E2P fills in the cplt_s of theevent bus with the return status and returns the same status as a returnvalue.

DM_P2E—Property to Event Adapter

[4169]FIG. 133 illustrates the boundary of the inventive DM_P2E part.

[4170] DM_P2E is an adapter that converts the I_A_PROP operationsreceived on its input into EV_PRP_REQ events, which are sent out itsoutput. There is a one-to-one correspondence between the two interfaces.The events that DM_P2E generates are expected to be completedsynchronously.

[4171] 6. Boundary

[4172] 6.1. Terminals

[4173] Terminal “in” with direction “In” and contract I_A_PROP. Note:Input for property operation requests. DM_P2E converts these requestsinto EV_PRP_REQ events and sends them out its out terminal.

[4174] Terminal “out” with direction “Out” and contract I_DRAIN. Note:Output for synchronous EV_PRP_REQ events.

[4175] 6.2. Events and Notifications Outgoing Event Bus Notes EV_PRP_REQB_EV_PRP DM_P2E sends this event out its out terminal in response tobeing invoked on its in terminal.

[4176] 6.3. Special Events, Frames, Commands or Verbs

[4177] None.

[4178] 6.4. Properties

[4179] None.

[4180] 7. Encapsulated interactions

[4181] None.

[4182] 8. Specification

[4183] 9. Responsibilities

[4184] 3. Convert I_A_PROP requests received on in to EV_PRP_REQ eventrequests and send them out the out terminal.

[4185] 10. Theory of Operation

[4186] 10.1. State Machine

[4187] None.

[4188] 10.2. Mechanisms

[4189] None.

DM_PSET and DM_PSET8—Property Setters

[4190]FIG. 134 illustrates the boundary of the inventive DM_PSET part.

[4191]FIG. 135 illustrates the boundary of the inventive DM_PSET8 part.

[4192] DM_PSET issues a property set request when it receives a triggerevent on its input. The property name and type are given to DM_PSET asproperties. DM_PSET can also retrieve the value of the property from theevent bus of the trigger event

[4193] DM_PSET8 combines eight DM_PSETs to set up to eight properties onthe trigger event. The parts have no state.

[4194] 11. Boundary

[4195] 11.1. Terminals

[4196] Terminal “in” with direction “In” and contract I_DRAIN. Note:v-table, synchronous, infinite cardinality When the trigger event isreceived on this terminal, DM_PSET/DMPSET8 sends a property set requestthrough the out terminal; otherwise return CMST_NOT_SUPPORTED.

[4197] Terminal “out” with direction “Out” and contract I_DRAIN. Note:v-table, synchronous, cardinality 1 Output for property set requests.

[4198] 11.2. Events and Notifications

“out” Terminal

[4199] Outgoing Event Bus Notes EV_PROP_REQ B_EV_PROP Request propertyset operation. The event bus is dynamically allocat- ed and has only theCMEVT_A_SYNC attribute set.

[4200] 11.3. Special Events, Frames, Commands or Verbs

[4201] None.

[4202] 11.4. Properties (DM_PSET)

[4203] Property “trigger” of type “UINT32”. Note: Trigger event ID onwhich to set the property; 0 means any event. The default value isEV_PULSE.

[4204] Property “name” of type “ASCIZ”. Note: Name of property to set;empty means don't set. The default value is “”.

[4205] Property “type” of type “UINT32”. Note: Type of property to set(CMPRP_T_XXX). The default value is CMPRP_T_UINT32.

[4206] Property “value” of type “UINT32”. Note: Value to set. For stringand binary property types, ‘value’ should be set to a pointer to thestring. This property is ACTIVETIME and the default value is 0. Thisproperty is used only if the offset property is −1.

[4207] Property “offset” of type “UINT32”. Note: Offset of value intrigger event bus if the value is be retrieved from the bus. The defaultvalue is 0×fffffff (−1); do not retrieve value from bus; use thecontents of the value property.

[4208] Property “by_ref” of type “UINT32”. Note: If TRUE, the value inthe bus is by reference. If FALSE, the value is contained in the bus.Used only if offset is not −1. The default value is FALSE.

[4209] Property “size” of type “UINT32”. Note: Size of the propertyvalue [in bytes]. This property is used only for binary property types.The default value is 0.

[4210] 11.5. Properties (DM_PSET8)

[4211] Property “trigger” of type “UINT32”. Note: Trigger event ID onwhich to set the property; 0 means any event. The default value isEV_PULSE.

[4212] Property “p1.name . . . p8.name” of type “ASCIZ”. Note: Name ofproperties to set; empty means don't set. The default value is “”.

[4213] Property “p1.type . . . p8.type” of type “UINT32”. Note: Type ofproperties to set (CMPRP_T_XXX). The default value is CMPRP_T_UINT32.

[4214] Property “p1.value . . . p8.value” of type “UINT32”. Note: Valuesto set. For string and binary property types, ‘value’ should be set to apointer to the string. Each property is ACTIVETIME and the default valueis 0. Each property is used only if the pX.offset property is −1.

[4215] Property “p1.offset . . . p8.offset” of type “UINT32”. Note:Offset of value in trigger event bus if the value is be retrieved fromthe bus. The default value is 0×fffffff (−1); do not retrieve value frombus; use the contents of the value property.

[4216] Property “p1.by ref . . . p8.by_ref” of type “UINT32”. Note: IfTRUE, the value in the bus is by reference. If FALSE, the value iscontained in the bus. Used only if pX.offset is not −1. The defaultvalue is FALSE.

[4217] Property “p1.size . . . p8.size” of type “UINT32”. Note: Size ofthe property value [in bytes]. This property is used only for binaryproperty types. The default value is 0.

[4218] 12. Encapsulated Interactions

[4219] None.

[4220] 13. Specification

[4221] 14. Responsibilities

[4222] 1. When trigger event is received, send EV_PROP_REQ event withCMEVT_A_SYNC attribute set through the out terminal and return thestatus from the call. Note: DM_PSET8 returns the status of the firstproperty operation; the status of the remaining operations is ignored.

[4223] 2. Return CMST_NOT_SUPPORTED for all unrecognized events.

[4224] 15. Theory of Operation

[4225] 15.1. State Machine

[4226] None.

[4227] 15.2. Mechanisms

Determining Property Value

[4228] When DM_PSET receives a trigger event, it looks at its offsetproperty to determine where from to retrieve the property value. If theoffset property is 0×ffffffff, then it retrieves the property value fromits value property; otherwise, it retrieves the value form the eventbus.

Dereferencing Values (‘offset’ not 1)

[4229] If the by_ref property is FALSE, then the offset in the bus istreated as a byte location representing the first byte of the value. Ifthe by ref property is TRUE, then the offset is treated as a DWORD valuethat is converted into a pointer based on the property type.

Determining Property Size

[4230] DM_PSET determines the property size based on the property typeand or its size property.

[4231] If the property type is CMPRP_T_BINARY, the size propertycontains the value size, in bytes. The size property is only used forbinary property types.

[4232] If the property type is CMPRP_T_UINT32 or CMPRP_T_SINT32, DM_PSETassumes that the property size is 4.

[4233] If the property type is CMPRP_T_ASCIZ, CMPRP_T_UNICODEZ, orCMPRP_T_MBCSZ, the property size is the length of the string (in bytes)plus the terminating null character.

[4234] The CMPRP_T_UNICODEZ property type is not supported for VxDenvironment and the CMPRP_T_MBCSZ property type is only supported in W32environment. All other types are supported in all environments.

[4235] 15.3. Use Cases

Property Value Latching

[4236] The fact that the ‘value’ property is ACTIVETIME allows DM_PSETto be used as a property value latch. The value may be set on DM_PSET;and DM_PSET will send it out when it receives the trigger event. Note:this usage is available only with UINT32 property type.

[4237] 16. Dominant's Responsibilities (DM_PSET8)

[4238] 16.1. Hard Parameterization of Subordinates

[4239] DM_PSET8 does not perform any hard parameterization of itssubordinates.

[4240] 16.2. Distribution of Properties to the Subordinates Propertyname Type Distr To trigger UINT32 bcast pX.trigger p1.name . . . p8.nameASCIZ redir p1.name . . . p8.name p1.type . . . p8.type UINT32 redirp1.type . . . p8.type p1.value . . . p8.value UINT32 redir p1.value . .. p8.value p1.size . . . p8.size UINT32 redir p1.size . . . p8.sizep1.offset . . . p8.offset UINT32 redir pl.offset . . . p8.offsetp1.by_ref . . . p8.by_ref UINT32 redir p1.by ref . . . p8.by_ref

Dynamic Container DM_ARR_Part Array

[4241] DM_ARR (hereinafter “the array”), is a part, which is a dynamiccontainer for other parts. The set of parts can change dynamically atany time including when a DM_ARR instance is active. Once added to thecontainer, individual parts (called array elements or just elements) canbe parameterized, connected or activated through specialized(controlling) terminals that DM_ARR exposes.

[4242] Typical usage of the array is in an assembly (host) whichmaintains a dynamic set of parts of the same or similar classes. Forexample, in a device driver, all device instances can be maintained in apart array and the assembly can simply dispatch the input events to theproper instance.

[4243] The array utilizes the connection table of the host in order toestablish connections to its elements. All connections to the arrayitself specified in that connection table are treated as connections toan element of the array and established when a new subordinate is added.

[4244]FIG. 136 illustrates the boundary of the inventive DM_ARR part.

[4245] 1.1. Key Benefits

[4246] 1. Connections to a dynamic set of parts can be specified in astatic connection table and properly maintained. The benefit here isthat having this static information eliminates the need of having codethat maintains the same information.

[4247] 2. Specialized parts can be developed that do most of the workpertinent to array elements creation, destruction, parameterization andconnection, as well as dispatching, multiplexing and demultiplexing ofconnections, therefore eliminating the need to have this code in thehost.

[4248] 3. The one-to-many relationship and the dynamism of the structureare encapsulated into a single part. This allows restricting theirproliferation into other portions of the design, which can becomesimpler.

[4249] 1.2. More Information

[4250] The elements of the array can be of different classes. The arraysupports a default class name, which will be used when new elements areadded to create them. The creator has the option to override the defaultclass name and supply a new one.

[4251] The array exposes properties and terminals of its elements at itsown boundary, allowing the outer scope to connect to and parameterizethem directly using the standard ClassMagic mechanisms available.

[4252] DM_ARR implements a dynamic set of properties, which aresynchronized between all subordinates. This mechanism is analogous tothe group property mechanism in ClassMagic. The difference is that inthe array, the group is defined as all elements and changes whenever anelement is added or removed. The storage for the property values isprovided by the array.

[4253] 1.3. Notes

[4254] The connections to the array may be established to more than oneelement in the array. This means that terminals of objects outside thearray that can be connected to terminals on the array (andconsecutively, to terminals of objects inside the array) havecardinality at least as high as the maximum number of objects that willbe created in the array. As input terminals normally have infinitecardinality, this note affects mostly outputs and bidirectionalterminals. Such terminals are may be DriverMagic mux terminals orprovide the required cardinality in another way.

[4255] The array acts on behalf its host for the purposes of memoryallocation, connection table interpretation, etc. In order to accomplishthis, the array is given an interface that allows the array to examinethe connection table of its host assembly as well as the objectidentifiers of the specific part instances in this assembly. This allowsthe array to establish all described connections between a newly createdelement and parts in the host assembly, as those connections aredescribed in the connection table of the host assembly. The way in whichthe array receives this information can be varied; differentimplementations are possible and are surely apparent to one skilled inthe art to which the present invention pertains.

[4256] Specialized parts can be developed which, when connected to thecontrolling terminals, ensure the proper life cycle of the arrayelements. In this case the assembly needs to perform only instancedispatch. In most cases, even that can be avoided by having additional“dispatch” parts and a proper set of “interface adapter” parts.

[4257] 1.4. Usage

[4258] DM_ARR provides a special macro for easy inclusion of part arrayinstances in the table of subordinates. To use this macro, includeDM_ARR.H header file after CMAGIC.H/CMAGIC.HPP.

[4259] The syntax of this macro is described below.

[4260] array

[4261] Description: Declares a subordinate of class DM_ARR andhard-parameterizes this subordinate as necessary.

[4262] Syntax: array (name, dflt_class, gen_ids)

[4263] Arguments: name name of the array; this name can be used toestablish connections to/from the array

[4264] dflt_class default class name to use for new elements

[4265] gen_ids TRUE if the array is supposed to generate IDs for itselements; FALSE if the these are supplied from the outside

[4266] Example: SUBORDINATES

[4267] part (P1, P1_CLASS)

[4268] part (P2, P2_CLASS)

[4269] part (controller, C_CLASS)

[4270] part (bus, CM_EVB)

[4271] array (array, ELEMENT_CLASS, CMARR_GEN_KEYS)

[4272] param (array, repeated, “out2”)

[4273] param_uint32 (array, prop1, 5)

[4274] END_SUBORDINATES

[4275] CONNECTIONS

[4276] connect ($, mux, array, in)

[4277] connect (controller, fact, array, fact)

[4278] connect ($, out, array, out2)

[4279] connect (array, out1, P1, term)

[4280] connect (array, nfy, bus, evt)

[4281] END_CONNECTIONS

[4282] Remarks: This macro is for use only within the table ofsubordinates. Instead of using TRUE or FALSE as third argument, you canuse CMARR_GEN_KEYS or CMARR_USE_KEYS, which provide more meaningfulrecord of how the array instance is used.

[4283] See Also: param, param_xxx, connect

[4284] The macro expands to a statement for a regular subordinate partin an assembly, specifying the class name of said subordinate as DM_ARR.Here is the definition of the array macro:

[4285] #define array(nm,cis,keys)\

[4286] part (nm, DM_ARR)\

[4287] param (nm, ._name, #nm)\

[4288] param (nm, .class, #cls)\

[4289] param (nm, .gen_keys, keys )

[4290] 2. Boundary

[4291] 2.1. Terminals

[4292] Terminal “fact” with direction “In” and contract I_A_FACT. Note:Subordinates factory. Allows creation, destruction, life cycle controland enumeration of subordinates.

[4293] Terminal “prop” with direction “In” and contract I_A_PROP. Note:Direct access to properties of subordinates by key.

[4294] Terminal “conn” with direction “In” and contract I_A_CONN. Note:Connections. Allows connecting subordinates by key or name. Connectionto/from terminals of the host are also possible.

[4295] 2.2. Properties

[4296] Property “._sid” of type “UINT32”. Note: Self ID of the hostassembly. Used to retrieve information from the Radix (ClassMagic orDriverMagic) instance data including subordinates and connection tables.This property is mandatory.

[4297] Property “._name” of type “ASCIZ”. Note: Array instance name.This is the name of the array as known in the host. This property ismandatory.

[4298] Property “.auto activate” of type “BIN (fixed size)”. Note: Setto TRUE to make DM_ARR automatically activate every new subordinate ifit (DM_ARR) is in active state. If FALSE, new subordinates can beactivated explicitly, through the fact terminal. Default is FALSE.

[4299] Property “.class” of type “ASCIZ”. Note: Default class name ofthe parts added to the array. Default means not specified. Default isan.

[4300] Property “.gen_keys” of type “BIN (fixed size)”. Note: Set toTRUE to make DM_ARR generate keys for each part created in the partarray. Set to FALSE to make DM_ARR associate an externally provided keyfor each part created in the part array. This property is mandatory.

[4301] Property “._fact” of type “ASCIZ”. Note: Name of the subordinatesfactory terminal (I_A_FACT) Default is “fact”.

[4302] Property “._prop” of type “ASCIZ”. Note: Name of the subordinatesproperty terminal (I_A_PROP) Default is “prop”.

[4303] Property “._conn” of type “ASCIZ”. Note: Name of the subordinatesconnections terminal (I_A_CONN) Default is “conn”.

[4304] Property “.repeated” of type “ASCIZ”. Note: Custom implementedproperty. Used to define the names of repeated (virtual) terminalsvisible at the boundary of the array. Get operation is not supported.Check operation is supported and will determine if a terminal can besuccessfully added.

[4305] The properties ._fact, ._prop and ._conn allow renaming of thecontrolling terminals of the array, so that an instance of the array canbe created as an element in another instance of the array and itscontrolling terminals can be connected.

[4306] The property repeated is a property that can be set multipletimes. The array accumulates the values set in this property (instead ofreplacing the value with the last set value). The array preferably keepsa list of all values set in the repeated property on its instance.

[4307] 3. Responsibilities

[4308] It is important to realize that a major portion of thefunctionality- and consequent benefit—of the array comes throughfunctionality that the array provides on its component boundary, and notonly the from the functionality the array exposes through its terminals.

[4309] In addition to the functionality made available through itscontrolling terminals (fact, prop, and conn), the array providesadvantageous functionality on its component boundary. As a component inthe DriverMagic component object model, the array receives requests toestablish connections on its terminals, to get and set properties, toenumerate properties, to activate and deactivate itself, and manyothers. A responsibility of the array is to implement these operationsin a way that allows the host assembly to view the array of dynamicallychangeable set of parts as a static part with terminals of multiplecardinality. Most of the advantageous functionality of the array ispreferably provided through this boundary.

[4310] Another responsibility of the array is to provide all itsmechanisms in a way that is independent of any specific part class thatwill be contained.

[4311] Additional responsibilities of the array include:

[4312] 1. Maintain a dynamic set of parts (subordinates) which maychange at all times.

[4313] 2. Expose all terminals on subordinates as terminals on the arrayessentially maintaining a dynamic set of terminals.

[4314] 3. Support a static set of properties for the purposes of regularparameterization. Support one custom property for the purposes ofdefining virtual terminals.

[4315] 4. Redirect all property operations for properties qualified with[<key value in hex. or dec. >] at the beginning to the respectivesubordinate identified by the key extracted from the name. Strip thequalifier before redirecting.

[4316] 5. Support a dynamic set of virtual group properties, where thegroup is defined as all current and future subordinates. Create a newgroup property every time the outer scope attempts to set a new propertyon the array, which cannot be redirected.

[4317] 6. Expose controlling terminals: factory for subordinates,connection of subordinates to other parts (incl. other subordinates) andmanipulation of properties on subordinates by key. Support mechanism forrenaming these terminals through properties.

[4318] 7. Support virtual terminals for connecting to redirected orrepeated outputs on the host. Use property mechanisms to define thenames of these terminals. Enforce that these terminals are simpleoutputs with cardinality 1.

[4319] 8. Reject all connections to non-virtual terminals as NOP (nooperation) if attempted from the array's outer scope. Establish manuallyall connections to a subordinate upon its creation using the informationfrom the connection table in the host. Interpret connections to thearray as connections to the subordinates.

[4320] 4. Theory of Operation

[4321] DM_ARR maintains a dynamic set of subordinates preferably usingthe available Part Array API in the ClassMagic engine. All functionalitypertinent to the maintenance and operation of this set is delegated tothis entity. The part array API provides a simple means for holding anumber of part instances, creating and destroying them dynamically, andperforming connection and property operations on them. All that it doesis keep a list (or array) of part object identifiers (oid) for createdobjects, and when an operation is requested, the part array API locatesthe specific part instance and forwards the operation to the normalClassMagic API (or component model API as it may be the case in othersystems). The functionality of the part array API is documented indetail the ClassMagic and DriverMagic Reference manuals. Implementationsof said API or implementing DM_ARR without using this API is surelyapparent to one skilled in the art to which the present inventionpertains.

[4322] DM_ARR adds value to this functionality primarily by makingpossible to access terminals and properties of these subordinates as ifthey were terminals and properties on the DM_ARR itself, and byautomatically establishing all connections described in the connectiontable of the host between elements of the array and other parts in theassembly. This allows a dynamic set of subordinates to be included as astatic part in an assembly (by inserting DM_ARR in place of the dynamicset and connecting it with all the connections that would be requiredfrom each element of the dynamic set).

[4323] In addition DM_ARR provides specialized terminals forprogrammatic control of the Part Array container (controllingterminals). The implementation of these terminals essentially isdelegated to the Part Array entity as well.

[4324] DM_ARR implements the following basic mechanisms in order toaccomplish what it does.

[4325] 4.1. Virtual Terminals

[4326] Virtual terminals are simple output terminals with cardinality 1exposed on the boundary of the DM_ARR instance (the array). The purposeof these terminals is to collect the connection information when aconnection to them is established. This information is used to repeatthe connection attempt (replicate) to all subordinates, current andfuture.

[4327] The set of such terminals is explicitly specified by the array'souter scope and is communicated to the array through properties. Thisset does not change throughout the life scope of an array instance.Virtual terminals cannot be removed until the instance is destroyed. Theouter scope can establish the set of virtual terminals for a particulararray instance through hard parameterization.

[4328] Connections to virtual terminals can be established at all timesand these are replicated immediately to all currently existingsubordinates. When a new subordinate is created, all currentlyestablished connections to all virtual terminals are attempted to thissubordinate and if any of them fails for whatever reason, thesubordinate creation fails as well.

[4329] Note that virtual terminals are only one of the types ofterminals supported by the array on behalf of its elements. Anotherimportant feature supported by the array is the ability to establish allconnections for a newly created element, connecting the element to thesame parts and terminals to which the array itself is described to beconnected in the host assembly (excluding the array's controllingterminals fact, prop and conn).

[4330] 4.2. Array Properties

[4331] Properties defined as properties on the array itself areinterpreted as private properties of the array and are not included inany mechanisms for storage or distribution to subordinates. This alsoimplies that their names are reserved for internal use of the array andcannot be used as names of group properties on the array. These namesare intentionally prefixed with dot “.”, to lower the possibility ofname conflict.

[4332] One of the array properties has a completely customimplementation. This property is used to define the set of virtualterminals available on the array. Any attempt to set such property, uponsuccess, will result in creating a new virtual terminal and thisterminal will become immediately available for connections. Operationget is not supported and will return CMST_NOT_SUPPORTED. Operation chkwill check if the addition of a new virtual terminal with that name ispossible or not.

[4333] 4.3. Virtual Properties

[4334] Virtual Properties are a dynamic set of properties on the array,which are intended to be distributed to all subordinates whenever theybecome available. This set changes every time a new property is set onthe array. The underlying mechanism for storage and distribution of theproperty values is the one found in a group property.

[4335] The values, and preferably, the types, of the virtual propertiesset by the outer scope are stored and remembered by the array and in thesame time distributed to all currently existing subordinates the sameway this is done with group properties.

[4336] When a new subordinate is created, all virtual properties thathave been set in the life scope of the array (and currently remembered)are set on that subordinate ignoring any errors related to whether suchproperty exists or not. If other errors occur, a warning is issuedthrough the ClassMagic API for error medium access.

[4337] The get operation is equivalent to the get operation on a groupproperty—the value is retrieved from the storage in the array and nosubordinates are involved in the process. Other methods of retrievingthe value of the virtual property are possible (e.g., get the value ofthat property from the first subordinate, if said subordinate exists),and should be apparent to one skilled in the art to which the presentinvention pertains.

[4338] This mechanism in this embodiment of the array does not supportUPCASE and RDONLY property attributes. Mandatory properties are notdirectly supported, however, if any of the subordinates has mandatoryproperties and these are not set before activation, the activation ofthe subordinate will fail and the proper diagnostic message will belogged in the checked versions of the ClassMagic engine.

[4339] 4.4. Redirected Properties

[4340] These are properties beginning with a key qualifier [<key valuein hex or dec. >] or [<key value in hex. or dec. >]. DM_ARR simplystrips the qualifier and redirects them to the proper subordinateessentially doing the same as any assembly would do. DM_ARR uses the keyvalue in the qualifier string to determine which subordinate to redirectto.

[4341] No storage is provided for such properties. DM_ARR only acts as aredirector.

[4342] 4.5. Enumeration of Properties

[4343] As any other part, DM_ARR presents a property namespace to theouter scope, preferably constructed in the following manner (and order):

[4344] 1. All properties on the array itself excluding the custom ones(virtual terminals) and all properties starting with “_”.

[4345] 2. All virtual properties currently existing on the array. Theseare the properties set by the outer scope until before the particularenumeration operation was commenced. The property operations areprotected—other execution contexts will be blocked or refused entryuntil the operation is complete.

[4346] 3. All properties of all subordinates in unspecified order. Theseare the properties beginning with a key qualifier [<key value in hex. ordec. >].

[4347] 5. Main data structures and other definitions

[4348] 5.1. VPROP—Virtual Property Table Entry // virtual property tableentry typedef struct VPROP { char *namep; // name of the property uint16type; // property data type void *valp; // pointer to value uint32 len;// length of the value } VPROP;

[4349] 5.2. VTERM—Virtual Terminal Table Entry // virtual terminal tableentry typedef struct VTERM { char name[MAX_TERM_NM_SZ]; // virtualterminal name bool connected; // TRUE if terminal connected from outsidebyte conn_ctx[CONN_CTX_SZ]; // connection context } VTERM;

[4350] 5.3. CONN_NDX—Connection Index typedef struct CONN_NDX { _hdlconn_h; // connection handle VTERM *vtp; // virtual terminal instance ID(NULL if not virtual) bool left; // TRUE if the array terminal is on theleft side // of the connection (as per get_info) } CONN_NDX;

[4351] The DM_ARR uses this structure to maintain the index entry forconnection←→terminal map. Instances of this structure are allocated bythe array and added to a handle set using the ClassMagic API.

[4352] No random access is needed to this index and for this reason thehandle values associated with each instance of this structure are notstored anywhere. Only enumeration of these instances is possible whichprovided by the ClassMagic API for handle management.

[4353] 5.4. S_PROP_QRY—Enumeration States enum S_PROP_QRY { S_PQ_ARRAY,// array properties S_PQ_VPROP, // virtual properties S_PQ_SUBS, //properties of subordinates };

[4354] The property query state machine uses this enumerated type todetermine the next state in the enumeration. Each state is associatedwith a class of properties currently being enumerated. As the arrayimplements joined name spaces for these classes, the state is needed toidentify the current one.

[4355] The transition is purely sequential in the order in which thesestates are defined. Backward enumeration of properties and thereforebackward state transition are not possible.

[4356] 5.5. PQ_ARRAY—Property Query Context in the S_PQ_ARRAY State

[4357] typedef struct PQ_ARRAY { _ctx enum_ctx; // current propertyenum.ctx } PQ_ARRAY;

[4358] This structure represents the property query context inS_PQ_ARRAY state. This is the state in which the properties listed onenumeration are these defined on the array itself, skipping propertieswhose names begin with “._”.

[4359] 5.6. PQ_VPROP—Property Query Context in the S_PQ_VPROP State

[4360] typedef struct PQ_VPROP { _ctx enum_ctx; // current virt. prop.enum. ctx } PQ_VPROP;

[4361] This structure represents the property query context inS_PQ_VPROP state. This is the state in which the virtual properties arelisted on enumeration.

[4362] The context is the one returned by the virtual propertyenumeration helper API.

[4363] 5.7. PQ_SUBS—Property Query Context in the S_PQ_SUBS State

[4364] typedef struct PQ_SUBS { _ctx enum_ctx; // part array enumerationcontext bool curr_1st; // TRUE to start from the first property dwordcurr_oid; // current subordinate in the array _ctx curr_qryh; // queryhandle on current subordinate } PQ_SUBS;

[4365] This structure represents the property query context in S_PQ_SUBSstate. This is the state in which the properties of subordinates(elements) of the array are listed on enumeration.

[4366] Both the current subordinate and the property enumeration contexton that subordinate are kept. There is also an indication whether theenumeration has to start from the first property of the current elementor to continue from the current one.

[4367] 5.8. PROP_QRY—General Property Query Context typedef structPROP_QRY { uint state; // enumeration state flg32 attr_mask; // queryattributes mask flg32 attr_val; // query attributes values unionPQ_ENUM_STATE // query state depending on the state { PQ_ARRAY array;PQ_VPROP vprop; PQ_SUBS subs; }; } PROP_QRY;

[4368] This structure represents the composite property query instance.It combines the current state of property enumeration in a queryinstance together with the particular contexts for each individualstate. It is assumed that there is no context shared between differentstates.

[4369] 6. Self Data Structure (instance data) BEGIN_SELF DM_ARR_HDR arr;// Part Array from DriverMagic VECON vtc; // virtual terminals containerVECON vpc; // virtual properties container VTDST vtd; // virtualterminal operation distributor VPDST vpd; // virtual property operationdistributor _hdl cnx; // connection index owner key _hdl qry; // queriesowner key I_META *host_imetap; // host meta-object interface // used toresolve subordinate name to oid I_R_ECON *iecnp; // connectionenumeration interface // used to enumerate the connections in the hostRDX_CNM_DESC *cdscp; // connection descriptor in the host

[4370] PROPERTIES RDX_SID sid; // self ID of the host boolauto_activate; // TRUE to auto-activate bool gen_keys; // TRUE togenerate keys char name [RDX_MAX_PRT_NM_LEN + 1]; // array name charcls_nm[RDX_MAX_PRT_NM_LEN + 1]; // default class name char _fact[RDX_MAX_TRM_NM_LEN + 1]; // ′fact′ terminal name char _prop[RDX_MAX_TRM_NM_LEN + 1]; // ′prop′ terminal name char _conn[RDX_MAX_TRM_NM_LEN + 1]; // ′conn′ terminal name

[4371] TERMINALS

[4372] decl_input (fact, I_A_FACT)

[4373] decl _input (prop, I_A_PROP)

[4374] decl_input (conn, I_A_CONN)

[4375] END_SELF

[4376] 7. State Machine Organization

[4377] A state machine is used for property enumeration. The inputevents are three: “reset”, “next” and “current”. The machine performssequential state transition in the order in which the states aredefined. Transition to initial state is possible at any state and willhappen if “reset” event is received.

[4378] The input events are declared in the following enumerated type:enum PQ_EVENT { PQ_EV_RESET = 0, PQ_EV_NEXT = 1, PQ_EV_CURR = 2, };

[4379] All events are fed into a state machine controller—a staticfunction responsible to invoke the proper action handler as defined inthe state transition table. The action handler is responsible to performthe state transition before it returns to the controller.

[4380] The prototype of such action handler is shown bellow:

[4381] typedef_stat pq_ahdir (PROP_QRY *sp, SELF *selfp, B_PROPERTY*bp);

[4382] The state machine event feeder (controller) prototype is shownhere:

[4383] static _stat pq_sm_feed (PROP_QRY *sp, SELF *selfp, uint ev,B_PROPERTY *bp);

[4384] The state transition table associates three action handlers foreach state: “reset”, “next” and “current” action handlers. typedefstruct SM_TBL_ENTRY { pq_ahdlr *reset_hdlrp; pq_ahdlr *next_hdlrp;pq_ahdlr *curr_hdlrp; } SM_TBL_ENTRY;

[4385] State transition table: static SM_TBL_ENTRY g_sm_table [] = { /*PQ_EV_RESET *//* PQ_EV_NEXT *//* PQ_EV_NEXT */ /* S_PQ_ARRAY */ ah_reset, ah_arr_next , ah_arr_curr , /* S_PQ_VPROP */ ah_reset , ah_vp_next ,ah_vp_curr , /* S_PQ_SUBS */ ah_reset , ah_subs_next , ah_subs_curr , };

[4386] See the DM_ARR part implementation design in Appendix 5 for moredetails on the described embodiment. Also see the Appendix 14 for theinterfaces exposed by the DM_ARR part.

[4387] 8. Mechanisms

[4388] This section contains a brief overview of some of the DM_ARRmechanisms. For additional details on the preferred embodiment, see theappropriate Appendix.

Redirected Properties

[4389] Operations on these properties are redirected (using the keyvalue in the qualifier) to the respective subordinate in the Part Arrayentity. The determination whether or not to use this mechanism is basedon the first character in the property name. If that character is “[”,this mechanism is used, otherwise the property is considered virtual.

[4390] Property can also be considered virtual if the syntax of thequalifier is unrecognized. The only recognized syntax is “[<hex. or dec.value>]” or “[<hex. or dec. value>].”. For example, “[abcd].prop” hasunrecognized syntax and will not be considered redirected. Operations onproperties with syntax “[*].prop” are equivalent to operations on avirtual property “prop”.

[4391] If a part with such key does not exist at the time of theproperty operation, the operation fails.

Virtual Group Properties

[4392] DM_ARR uses the handle manager provided by the engine to keep theset of virtual properties. The host memory allocator is used for allallocations including the property name and storage for the value.

[4393] Every time a new property is set, the set of virtual propertiesis enumerated using the owner key for this set and if this property wasnot found (was not previously set), it is added by allocating aninstance of the VPROP data structure and associating it with a handle.All storage is allocated using allocation on behalf of the host. Getoperation works off the storage retrieving the information directly fromthere.

[4394] Once a virtual property is added, the set of subordinates isenumerated and the property value is set to them as well. If theproperty is not found, this condition is ignored.

[4395] This mechanism works independently of the fact whether there areany subordinates or not. When new subordinate is created, the virtualproperty mechanism enumerates the set of all currently existingproperties and attempts to set each of them to the new subordinate,following the same logic as for setting on existing ones.

[4396] In all cases warnings will be logged in case setting a propertyon a subordinate fails for any reason other than the property is notfound. These warnings will appear only in checked versions of theengine.

Custom Property

[4397] To properly maintain the virtual terminal mechanism, DM_ARR usesa custom property implementation for one of its properties. Theoperation set on this property has the meaning of “create”.

[4398] Every time this custom property is set, a new virtual terminal iscreated with name the property value supplied to the set operation. Incase there is a duplicate and/or the creation of a virtual terminalfails for any reason, the set operation fails as well.

[4399] Operation chk on this property checks for duplicate name of avirtual terminal and fails if there is a duplicate.

[4400] Operation get on this property is not supported and returnsST_NOT_SUPPORTED.

[4401] This mechanism uses the Virtual Terminal mechanism to accomplishwhat it does.

Virtual Terminals

[4402] Virtual terminals are maintained only for connections toredirected or repeated outputs on the host. These terminals are createdthough the operations on a special custom property on the array.

[4403] Virtual Terminal mechanism uses the handle manager provided inClassMagic to maintain the set of virtual terminals existing on theparticular instance of the array.

[4404] For each virtual terminal, a special control block is allocatedwhich will contain the connection information (once this terminal isconnected from the outside) and a handle is created and associated withthis control block. The connection context upon creation is initializedto 0 the terminal is marked as unconnected.

[4405] When a virtual terminal is connected to, the mechanism stores theconnection context supplied by the counter terminal into the storageprovided in the control block, replicates the connection to all currentsubordinates and indicates that the connection was successful. At thispoint, the mechanism marks the terminal as connected.

[4406] When a subordinate is created, the mechanism enumerates allvirtual terminals skipping the unconnected ones and repeats theconnection to the subordinate supplying the connection context stored inthe terminal on connect operation. The mechanism uses the ConnectionIndex to map connections to terminals.

Enumeration of Properties

[4407] On enumeration properties are given out in the following order:

[4408] 1. Custom property values set on the array. The values are listedunder the property name “.repeated” and all virtual terminals are givenas values.

[4409] 2. Other properties defined on the array in the order they aredefined. “.repeated” and “._<xxx>” properties are skipped.

[4410] 3. Virtual group properties in no particular order.

[4411] 4. Properties from the namespaces of the subordinates prefixed bythe array element qualifier: “[<key value in hex. or dec. >]” or “<keyvalue in hex. or dec.>].” depending on whether the subordinate propertystarts with “[” or not.

[4412] This mechanism keeps an enumeration state associated with eachproperty query. This state is kept in a PROP_QRY structure described insection below.

[4413] The state transition is sequential in the order defined by theS_PROP_QRY enumerated type. Any property enumeration operation can forcea state transition to the next or previous state when the current subsetof properties is exhausted.

Connection Index

[4414] Connection Index mechanism facilitates fast connection of newlycreated subordinates. Essentially it provides a map between connectionsand terminals on the array including the virtual ones.

[4415] For each connection to the array specified in the connectiontable of the host assembly, the index entry contains the name of thearray terminal, the enumeration context associated with the connectionand the handle to a virtual terminal. If the connection is not to avirtual terminal, the handle is 0.

[4416] This index is built during activation by enumerating theconnection table and for each connection resolving the handle of thevirtual terminal participating in that connection (if any).

[4417] Special care is taken to ensure that there is at most oneconnection to/from a virtual terminal as these terminals are assumedsimple outputs with cardinality 1. If not, the array will not activate,will log an error and return ST_REFUSE.

[4418] The connection index uses the CONN_NDX data structure describedbelow.

[4419] This mechanism offers only enumeration interface to this table.

[4420] 8.1. Use Cases

Legitimate Connections

[4421] The legitimate connections of interest are shown in FIG. 137. Thesubordinates and connection tables will look like:

[4422] SUBORDINATES

[4423] part (P1, P1_CLASS)

[4424] part (P2, P2_CLASS)

[4425] part (controller, C_CLASS)

[4426] part (bus, CM_EVB)

[4427] array (array, Part, CMARR_GEN_KEYS)

[4428] param (array, “.repeated”, “out2”)

[4429] END_SUBORDINATES

[4430] CONNECTIONS

[4431] connect ($, mux, array, in)

[4432] connect (controller, fact, array, fact)

[4433] connect ($, out, array, out2)

[4434] connect (array, out1, P1, term)

[4435] connect (array, nfy, bus, evt)

[4436] END_SUBORDINATES

[4437] Step 1. Subordinates in the Assembly dominant are created. Whenthe ASSEMBLY dominant (the host) is created, ClassMagic createsinstances of all parts specified in the subordinates' table includingthe array. The array class is DM_ARR and this is hidden by the arraydeclaration macro.

[4438] Step 2. Hard parameterization phase. Immediately after creation,ClassMagic performs hard parameterization of them using again theinformation in the subordinates' table. There is only one parameter seton the array “.repeated”. ClassMagic will set this property with thevalue specified: out2. As this is a special property (custom), this willtrigger creation of a virtual terminal out2 which will be marked as“unconnected” at this time.

[4439] Step 3. Connection phase. The connection manager (CM) inClassMagic will attempt to establish all connections as specified in theconnection table including all connections to/from the array. The arraywill return ST_NOP on all of them except connections to/from out2 (#4)which is a virtual terminal. The connection broker (CB), who willactually perform the connection protocol, will forward this status tothe CM, who in turn will just ignore this connection. When theconnection to out2 terminal of the array is established, this time theAssembly will return the special ST_NOP indicating that this terminalcannot be connected at this time.

[4440] Step 4. Subordinate in the array gets created. It is assumed thatthe array is active at this time, if not the fact terminal will returnST_NOT_ACTIVE. When this happens the array will enumerate the ConnectionIndex and for each index entry, will establish a connection between thenew subordinate and the connection counterpart as specified in theconnection table. The array resolves this counterpart by using get_curroperation and the connection enumeration context in the index entry (theenumeration context, or index, was stored in the table when theconnection index was constructed). For the cases when the connection isto a virtual terminal (handle is non-0), the array resolves thisterminal using the handle from the index entry and checks if thisterminal is connected from outside. If yes, the array replicates theconnection to the virtual terminal using the connection data stored inthe virtual terminal. If this virtual terminal is not connected, it isskipped. For cases when the connection is not to a virtual terminal, thearray establishes the connection.

[4441] Step 5. Connection to a virtual terminal is established. This mayhappen both at “active” or “inactive” time. The array gets the acquireand connect operations on its terminal interface implementation. Itenumerates the virtual terminals in attempt to determine if that's aconnection to a virtual terminal. It does that by name comparison. Onacquire the array basically does nothing, except to supply emptyconnection data. On connect, the terminal interface implementationstores the connection data into the virtual terminal storage (provided)and marks it as connected. The array replicates the just establishedconnection to the virtual terminal to all of its elements using the nameand connection data from the virtual terminal.

Contingencies

[4442]FIG. 138 illustrates an advantageous use of the inventive DM_ARRpart.

[4443] Possible illegal connections of interest are shown in FIG. 138.Connection 1 and 2 are illegal as both contain redirected output thatcrosses the boundary of the host without connection multiplexing.Connection 3 is illegal because the terminal on the array to which itrefers is not declared as “.repeated”.

[4444] SUBORDINATES array (array, Part, CMARR_GEN_KEYS) param (array,“.repeated”, “bidir”) // here we forgot to include “out1” as “.repeated”param (array, “.repeated”, “out2”)

[4445] END_SUBORDINATES

[4446] CONNECTIONS

[4447] connect ($, in, array, in)

[4448] connect ($, bidir, array, bidir)

[4449] 20 connect (array, out1, $, out)

[4450] connect (array, out2, $, out)

[4451] END_SUBORDINATES

[4452] This use case assumes that the instance of the array has beencreated and parameterized as indicated in the table of subordinates. Thehard parameterization will create two virtual terminals bidir and out2.

[4453] Step 1. Establishing connections 1 and 2. The dominant (host)will attempt to establish these connections in the connection phase (seeprevious use case).

[4454] Connection 1 attempt will fail both on the host side and on thearray side; 2 will fail only on the host side. The failures areindicated by returning status ST_NOP and these connections will beskipped by the Connection Manager (CM). In fact, no connections will beestablished at this time.

[4455] Step 2. Establishing connections by the host's outer scope. Atsome later time before activation, the host's outer scope may attempt toestablish any of the connections shown on the above figure. The attemptswill be delegated to the array by the host.

[4456] Connection 1 will be rejected by the array with status ST_NOP(the host must recognize this and remap the status to ST_REFUSE) as thein terminal is not a virtual one.

[4457] Connection 2 is not going to be rejected on the same basis; thearray will attempt to update the virtual terminal bidir and will failwith ST_REFUSE because the directions are incompatible: the array wouldexpect the counter terminal to be input.

[4458] Connection 3, when redirected from the repeated output on thehost, will succeed connecting the out2 terminal, but will fail when out1is attempted. The failure will be return status ST_NOP. This status willbe treated as an error by the repeated output on the host and remappedto ST_REFUSE so this connection will not be established.

[4459] The limitations described above pertain to the particularembodiment (based on the DriverMagic composition-based system) and arenot inherent limitations of the present invention.

Passing Information about the Host Assembly to DM ARR

[4460] The DM_ARR receives a special value in its _sid property. Thisvalue is a pointer to an interface, which allows the array to obtaininformation sufficient to enumerate the connections in the host assemblyand to be able to resolve the name of a subordinate part in the hostassembly (as mentioned in the connection description table) to an objectidentifier (oid), used when requesting the establishing of connections.

[4461] In this particular embodiment, the information obtained by DM_ARRincludes:

[4462] a pointer to the connection descriptor of the host assembly(RDX_CNM_DESC);

[4463] a pointer to an interface for enumerating the connections in aconnection descriptor (I_R_ECON);

[4464] a pointer to the instance data of the host assembly, providingthe ability to resolve the name of a subordinate part in the hostassembly to an object ID (oid), using a service similar to thecm_prt_sub2oid( ) API function in DriverMagic.

[4465] For more information on the connection descriptor see Appendix 3.RDX_CNM_DESC Structure. For more information on the interface forenumerating connection descriptors, see Appendix 4. I_R_ECON Interface.For more information on resolving subordinate name to oid, see thecm_prt_sub2oid API function in the C Language Binding Reference for theClassMagic Composition Engine [exact reference exists somewhere in thebeginning of the text].

[4466] 9. Details on mechanisms and helpers used in DM_ARR

[4467] 9.1. VECON—Virtual Entity Container

[4468] The virtual entity container is used for holding the set ofvirtual properties and for holding the set of virtual terminals.

[4469] The following structure is the instance data of a container forvirtual entities. typedef struct VECON { _hdl owner_key; // owner key ofthe handle set CM_OID oid; // memory owner uint32 off; // offset of namepointer } VECON;

[4470] The virtual entity container helper maintains a set of handlesassociated with an owner. The owner is kept on the owner_key field. Theoid field is used for ownership of the memory allocated by the helper.The memory allocation is performed on behalf of this object. The offfield is used to calculate the pointer to the name of particular entityby a base pointer supplied on all entity operations. For more

[4471] The following structure is the instance data of a distributor ofvirtual property values. typedef struct VPDST { DM_ARR_HDR *arrp; //array instance CM_OID  oid; // object to allocate memory on behalf of }VPDST;

[4472] The arrp field is used to identify the Part Array instance asprovided by ClassMagic. The oid field is used for ownership of thememory allocated by the helper. The memory allocation is performed onbehalf of this object.

[4473] For more details on the virtual property helper, see Appendix 8.VPDST—Virtual Property Distributor and Appendix 13. Interfaces Used byDescribed Mechanisms.

[4474] 9.4. VTERM—Virtual Terminal Helper

[4475] The virtual property helper is used to maintain data associatedwith a single instance of a virtual terminal. It uses the followingstructure to keep said data. typedef struct VTERM { char  *namep; //pointer to terminal name bool  connected; // TRUE if terminal connectedbyte  conn_ctx[CONN_CTX_SZ]; // connection context char name[MAX_TERM_NM_SZ]; // virtual terminal name word  sync; //synchronicity dword  attr; // terminal attributes } VTERM;

[4476] The instance data contains the name of the terminal (fixedlength), indication whether this terminal is connected and theconnection data (context), synchronicity and attributes supplied by thecounter terminal (if connected). The virtual entity container utilizesthe pointer to the virtual terminal name (namep field).

[4477] For more information on the virtual terminal helper, see Appendix9. VTERM—Virtual Terminal Helper and Appendix 13. Interfaces Used byDescribed Mechanisms. This helper is preferably used in conjunction withVTRME and VTRMI mechanisms described below.

[4478] 9.5. VTRME—Virtual Terminal Mechanism (Exterior)

[4479] This mechanism is used to handle requests to establish anddissolve connections for virtual terminals when said requests arereceived on the outside boundary of the array (i.e., requests typicallycoming from the ClassMagic engine when establishing connections insidethe host assembly). The VTRME mechanism uses the VTERM data structuredescribed above.

[4480] For more information on the virtual terminal mechanism forexterior requests, see Appendix 10. VTRME—Virtual Terminal Mechanism(Exterior) and Appendix 13. Interfaces Used by Described Mechanisms.

[4481] 9.6. VTRMI—Virtual Terminal Mechanism (Interior)

[4482] This mechanism is used to handle requests to establish anddissolve connections with virtual terminals of the array when saidrequests are received on the inside boundary of the array (i.e.,requests typically coming from the ClassMagic engine when the array hasrequested the connection of a terminal of an element part to the virtualterminal). The VTRMI mechanism uses the VTERM data structure describedabove.

[4483] For more information on the virtual terminal mechanism forinterior requests, see Appendix 11. VTRMI—Virtual Terminal Mechanism(Interior) and Appendix 13. Interfaces Used by Described Mechanisms.

[4484] 9.7. VTDST—Virtual Terminal Distributor

[4485] This mechanism is used when a connection to virtual terminal isbeing established from outside of the array, to distribute theconnection data to all present elements in the array.

[4486] The virtual terminal distributor uses the following datastructure as instance data: typedef struct VTDST { DM_ARR_HDR *arrp; //array instance ID CM_OID  oid; // object ID of the host } VTDST;

[4487] The arrp field is used to identify the Part Array instance asprovided by ClassMagic. The oid field is used for ownership of thememory allocated by the helper. The memory allocation is performed onbehalf of this object.

[4488] For more information on the virtual terminal distributor, seeAppendix 12. VTDST—Virtual Terminal Distributor and Appendix 13.Interfaces Used by Described Mechanisms.

[4489] 10. Example Architecture Using Part Array

[4490] This section provides an example of a driver architecture usingthe DM_ARR part array. The array is used to contain a dynamic set ofpart instances, one per each individual device that is serviced by thedriver.

[4491] The section consists of an architectural diagram, a functionaloverview, definition of principal entities (parts) and identification ofspecific interfaces between them.

[4492] This section is based on an actual driver, identified hereinafteras the MCP Driver. The architecture defined here, however, including theuse of the part array and surrounding parts, is universal and can beused for virtually any device driver.

[4493] With insignificant modifications, apparent to the one skilled inthe art, the same architecture and mechanisms can be used for a varietyof other software components and systems, such as COM and ActiveXcontrols, device drivers for other operating systems, applicationsubsystems, operating system service, and many others.

[4494] 10.1. Functional Description

Driver Scope

[4495]FIG. 139 illustrates a concentric view diagram of the MCP driverfor Windows. The top-level assembly (DRV) assembles the following parts:device factory (DM_FAC), device enumerator on registry (DM_REN), deviceparameterizer (DM_PRM), exception handler (DM_EXC) and part array(DM_ARR) which manages device driver instances (DEVxxx).

[4496] The DRV assembly is created when the driver is loaded. Itcontains a device instance factory (DM_FAC) that is responsible for thecreation, parameterization and destruction of all device instances(DEVxxx). DM_FAC utilizes DM_REN to enumerate installed devices and toaccess the resources allocated for them. During the driver'sinitialization, DM_REN is directed to read the list of devicesconfigured in the registry. For each device found by DM_REN, DM_FACcreates a device instance in DM_ARR and DM_PRM parameterizes it withsettings found in the Registry sub-key for the particular device.

Device Scope

[4497] The device instances DEVxxx created by DM_FAC implement theper-device functionality of the MCP driver. DEVxxx is a generic name fora set of classes; each class handles different communication media (xxxstands for the medium name; for example, DEVSER is for serial devices(RS-232), DEVPAR is for parallel devices (IEEE-1284), DEVUSB is forUniversal Serial Bus Devices). DM_ARR is capable of creating any ofthose (and other) classes. The only requirement to the class is that ithas terminals and properties as used by the DRV (which is the hostassembly for DM_ARR). For example, the particular DRV of the MCP driverrelies to be able to connect to terminals called ‘dio’ and ‘ext’ on theboundary of DEVxxx.

[4498] DEVxxx is an assembly of two major components:

[4499] (1) The MCP core assembly, MCC, converts the application requestsinto application messages.

[4500] (2) The transport assembly, TRAxxx, which encapsulates thetransport-specific functionality required to establish the communicationchannel with the device. It is responsible for acquiring exclusiveaccess to the communication driver; it also implements reliablecommunications protocol over the specified connection. TRAxxx providesan OS-independent and error-free transparent interface to device. Due toa differences in the serial/parallel port API in the target operatingsystems, TRAxxx has different implementation for Windows NT and Windows95/98.

Communications Protocol Core Scope

[4501] The MCC assembly is common for all devices. It contains two majorcomponents:

[4502] (1) The front end assembly, IF_IFA, which conditions anddispatches the requests from the application according to theirfunction.

[4503] (2) The session manager, SES, which is responsible for generatingapplication message requests (from incoming event requests) andsubmitting them out. When the response to a previously issued requestcomes, the session manager satisfies the pending event. SES accepts theincoming device notifications: all notifications are buffered inside ofSES and passed to the application upon request.

[4504] 10.2. Definition of Entities—Driver Scope

DRV—Driver

[4505] DRV is the top level assembly of the driver framework. Itassembles all the major components of the driver framework—DM_FAC,DM_PRM, DM_ARR, DM_REN and DM_EXC.

[4506] DRV exposes a single I_DRAIN input through which it receivesevents from the driver packaging.

DM_FAC—Device Factory

[4507] DM_FAC registers the dispatch handlers required for Windows WDMkernel mode device drivers (IRP_MJ_xxx functions).

[4508] DM_FAC handles all necessary interactions with the operatingsystem in order to register device driver instances. It receives all thecalls that WDM kernel mode device drivers must implement. DM_FACdispatches these calls to the appropriate instance of the device driver(DEVxxx).

[4509] DM_FAC uses the enumerator DM_REN to determine how many and whatdevice instances to create. DM_FAC utilizes DM_ARR to maintain the arrayof device instances.

[4510] In addition, DM_FAC sends a command to the parameterizer DM_PRMto read the device instance properties from the registry and configurethe specified device instance with them.

[4511] DM_FAC is a DriverMagic library part provided with the Windows NTDriver Kit and WDM Driver Kit. Refer to the Object Dynamics' Windows NTDriver Kit Reference and WDM Driver Kit Reference documents for acomplete description.

DM_REN—Registry Enumerator

[4512] DM_REN emulates device enumeration by reading the all sub-keys inthe driver's Registry key (Parameters\Device\sxxxx) and using the datafound in each as representing a device instance. DM_REN is a DriverMagiclibrary part. Refer to the Object Dynamics' DriverMagic User Manual fora complete description.

DM_PRM—Parameterizer from the Registry

[4513] DM_PRM reads the device settings from the registry and sends themto the device instance using property “set” requests on its o_prpoutput.

[4514] DM_PRM is a DriverMagic library part. Refer to the part libraryreference in the DriverMagic User Manual for a complete description.

DM_ARR—Part Array

[4515] DM_ARR is a dynamic container for other parts. The set of partscontained by DM_ARR can be changed dynamically at any time. DM ARRimplements all functionality necessary to manage the parts it contains.It works in conjunction with its host assembly to make its containedparts' terminals and properties visible to the host.

[4516] DM_ARR is a DriverMagic library part. Refer to the rest of thisdocument for a complete description.

DM_EXC—Exception Handler/Event Log

[4517] DM_EXC displays the exception events generated by DM_FAC to thedebug console and/or saves them in the Windows NT system event log orinto a text file in Windows 95/98.

[4518] DM_EXC is a DriverMagic library part. Refer to the part libraryreference in the DriverMagic User Manual for a complete description(Windows NT) and the DriverMagic WDM Driver Kit Reference (Windows95/98).

[4519] 10.3. Definition of Entities—Device Scope

[4520] The device driver assembly (DEVxxx) implements the corefunctionality of the driver. An instance of this assembly is created foreach installed device that is supported by the driver. DEVxxx consistsof the following major parts:

[4521] MCC—Communications Protocol Core sub-assembly. MCC converts theapplication requests into application messages.

[4522] TRAxxx—Transport interface sub-assembly. TRAxxx provides atransparent OS-independent error-free interface to device.

[4523] Following is a detailed description of the components that makeup DEVxxx.

DEVxxx—Device Assembly

[4524] DEVxxx assembles MCC, TRAxxx and DM_PEX. This allows the DEVxxxinternal structure to be invisible to the outside, so that the deviceportion of the driver can be created and used as a single component.

MCC—Communications Protocol Core

[4525] MCC is the device communication protocol assembly. It does notcontain device specific parts. MCC implements the appropriateApplication message protocol. MCC receives the application requests,converts them into application messages and sends them to the device. Itkeeps track of requests submitted and completes them when thecorresponding device responses are received. MCC receives all devicenotifications and stores them until the user-mode application acquiresthem.

TRAxxx—Transport Assembly

[4526] This assembly implements the device transport protocol. It isresponsible for acquiring exclusive access to the communication driverand detecting the device. TRAxxx implements the appropriate transportprotocol. TRAxxx provides a uniform interface for communication with thedevice applications. It has different implementation for the differenttransport media. The transport assembly contains parts that areoperating system specific; it has different implementations under thedifferent target systems.

DM_PEX—Property Exposer

[4527] DM_PEX gives any part connected to its prop terminal the abilityto access the properties of the assembly that DM_PEX it is containedwithin. It allows manipulation of assembly's properties (including itssubordinates) from a part connected to the assembly.

[4528] DM_PEX is a DriverMagic library part provided with Advanced PartLibrary. Refer to the part library reference in the Object Dynamics'Advanced Part Library document for a complete description.

Communications Protocol Core Scope

[4529] The MCC assembly and all parts in it are platform-independent.They are shared between Windows NT and Windows 95/98.

[4530] MCC contains of the following parts:

[4531] driver interface assembly-IF_IFA

[4532] session manager-SES

[4533] event sequencer-DM_SEQ

[4534] exception handler-DM_EXC.

IF_IFA—Interface Assembly

[4535] IF_IFA assembles parts that convert the incoming IOCTL requeststo self-contained events and distribute those events its various outputterminals according to their function. IF_IFA converts the incomingIOCTL requests to self-contained events sent out through call, nfy andprp terminals.

SES—Device Session Manager

[4536] SES is the device session assembly for MCP driver. It translatesthe requests incoming on its inputs into application messages and sendsthem out to the device. It keeps track of requests submitted andcompletes them when the corresponding device responses are received. SESreceives all device notifications and stores them until the user-modeapplication acquires them.

DM_SEQ—Event Sequencer

[4537] DM_SEQ distributes incoming events received on in to the partsconnected to the out1 and out2 terminals.

[4538] The events sent through outs and out2 can be completed eithersynchronously or asynchronously—DM_SEQ takes care of the propersequencing, completion and necessary cleanup.

[4539] DM_SEQ is used to distribute device life-cycle events between thesession manager and the transport assembly.

[4540] DM_SEQ is a DriverMagic library part provided with Advanced PartLibrary. Refer to the part library reference in the Object Dynamics'Advanced Part Library document for a complete description.

DM_EXC—Exception Handler/Event Log

[4541] DM_EXC displays the exception events generated by Session manager(SES) to the debug console and/or saves them in the Windows NT systemevent log or into a text file in Windows 95/98.

[4542] DM_EXC is a DriverMagic library part. Refer to the part libraryreference in the DriverMagic User Manual for a complete description(Windows NT) and the DriverMagic WDM Driver Kit Reference (Windows95/98).

[4543] 11. Assembly descriptor for DRV /*-----------------------------------------------------------------------*//* DRV: Driver Assembly */ /* */ /* DR_DRV.C - MCP Driver Assembly */ /*Version 1.00 $Revision: $ */ /*-----------------------------------------------------------------------*/// ClassMagic support #include <cmagic.h> #include <dm_arr.h> #include<i_dio.h> //for the DIO_MAP_BUFFERED const #pragma hdrstop // projectdefinitions #define MODULENAME “DR_DRV” #include <prjdefs.h> #include<re_ctl.h> // Exception message IDs. Generated // from re_ctl.mc#include <re_exctxt.h> // Exception messages text #ifdefined(PRJ_SDK_n3f) || defined(PRJ_SDK_n3c) #define _WIN_NT_PROJECT_#endif #define DFLT_CLASS_NAME “DEVSER” #define PKG_EXT_CLASS_MAPPRJ_REGISTRY_ROOT_9x“\\Parameters\\ExternalClassMap” /* --- SelfDefinitions----------------------- */ BEGIN_SELF decl_pass (drv) //properties DRIVER_OBJECT *drv_objp; // grp property storage END_SELF /*--- Default Implementations ----------------------*/ PART (DR_DRV, “MCPDriver Assembly”); /** --- Terminal/Property declarations---------------------*/ TERMINALS (DR_DRV) pass (drv) END_TERMINALSPROPERTIES (DR_DRV) prop_grp_uint32 (drv_objp  , fac, driver_objectp)#ifdef_WIN_NT_PROJECT_ prop_grp_uint32 (dry_objp  , exc, io_objectp  )#endif prop_bcast_unicodez (reg_root) prop_redir (dflt_class_name, fac,dflt_class_name) prop_redir (device_type , fac, device_type )END_PROPERTIES /** --- Subordinates ------------------------------*/SUBORDINATES (DR_DRV) part (fac, DM_FAC) param (fac, dflt_class_name,DFLT_CLASS_NAME  ) param (fac, buf_mapping , DIO_MAP_BUFFERED  ) param(fac, device_type , FILE_DEVICE_UNKNOWN) param (fac, status_xlat , 1 )// custom statuses // translated to // (s | 0xe0000000) #ifdef_WIN_NT_PROJECT_ param (fac, multiplex  , TRUE   ) #else param (fac,mux_dio , TRUE  ) param (fac, mux_ext , TRUE  ) param (fac, pnp ,FALSE  ) param (fac, copy_stkloc , FALSE  ) part (ldr, DM_PKGLDR) param(ldr, pkg_map_key , PKG_EXT_CLASS_MAP ) #endif part (prm, DM_PRM) part(ren, DM_REN) array (arr, DEVSER, CMARR_GENERATE_KEYS) // note: classname is // set from the outside #ifdef _WIN_NT_PROJECT_(—) part (exc,DM_EXC) #else part (exc, MCP_EXC95) param (exc, file_name ,EXC_LOG_FILE_NAME  ) param (exc, event_log , FALSE  ) param (exc,debug_output , TRUE  ) param (exc, file_name , EXC_LOG_FILE_NAME  )param (exc, fmt[0].id , FWK_INTERNAL_ERROR  ) param (exc,fmt[0].string , FWK_INTERNAL_ERROR_TXT  ) param (exc, fmt[1].id ,FWK_NO_DEVICES  ) param (exc, fmt[1].string , FWK_NO_DEVICES_TXT  )param (exc, fmt[2].id , FWK_DEV_ACTIVATE_FAILED  ) param (exc,fmt[2].string , FWK_DEV_ACTIVATE_FAILED_TXT) param (exe, fmt[3].id ,FWK_CREATE_ALIAS_FAILED  ) param (exc, fmt[3].string ,FWK_CREATE_ALIAS_FAILED_TXT) param (exc, fmt[4].id ,RRP_CLAIMED_FAILED  ) param (exc, fmt[4]string , RRP_CLAIMED_FAILED_TXTparam (exc, fmt[5].id , RRP_RES_CONFLICT  ) param (exc, fmt[5].string ,RRP_RES_CONFLICT_TXT  ) param (exc, fmt[6].id , RRP_UNCLAIMED_FAILED  )param (exc, fmt[6].string , RRP_UNCLAIMED_FAILED TXT ) #endifEND_SUBORDINATES /** --- Connections-------------------------------------*/ CONNECTIONS (DR_DRV) connect ($, drv , fac, drv  ) connect (fec, dio , arr, dio  )#ifdef_WIN_NT_PROJECT_(—) connect (fac, fac , prm, i_fac) #else connect(fac, fac , ldr, i_fac) connect (ldr, o_fac, prm, i_fac) connect (ldr,o_prp, prm, i_prp) #endif connect (fac, prp , prm, i_prp) connect (prm,o_fac, arr, fact ) connect (prm, o_prp, arr, prop ) connect (fac, edev,ren, edev ) connect (fac, eprp , ren, eprp ) connect (fac, exc , exc,exc ) END_CONNECTIONS

[4544] 12. Limits of the Implementation

[4545] The following list outlines the limitations of an embodiment ofthe inventive container, none of which is necessary for practicing thepresent invention as claimed herein and none of which is necessarilypreferred for the best mode of practicing the invention. Moreover, noneof the following should be viewed as a limitation on means envisioned inthe claims for practicing the invention as outlined herein above andbelow:

[4546] 1. DM_ARR is built for the ClassMagic object-composition engineused in the DriverMagic system, and thus can be used directly only withthat system. As a result, it is a DriverMagic component object, and cancontain only other component objects acceptable to DriverMagic. Thereason for choosing that system for the preferred embodiment is that, toinventors best knowledge, it is the only composition-based systemapplicable in a wide area of applications that does not sacrificeperformance.

[4547] 2. DM_ARR uses the ClassMagic part array API as means to create,destroy, connect and disconnect, manipulate properties and activationstate, maintain the list of contained objects, and other functions,related to the contained objects. The reason for using this API is thatthe ClassMagic engine provides it and, thus it was advantageous to usethe existing implementation.

[4548] 3. DM_ARR identifies object classes, terminals and properties bynames (text strings). Other identification mechanisms include withoutlimitation, Microsoft COM GUID, integer values, IEEE 802.3 Ethernet MACaddresses, etc. The reason for using names is that the DriverMagicsystem uses names to identify these entities, which makes it easy forpractitioners to remember and use.

[4549] 4. DM_ARR does not provide a built-in mechanism for dispatching(i.e., multiplexing or demultiplexing) multiple connections between anobject outside the container and one or more objects contained in thecontainer. When using this implementation, said dispatching ispreferably provided through separate adapter objects or by the outsideobjects, advantageously allowing the container to be used with a varietyof dispatch mechanisms.

[4550] 5. DM_ARR does not provide the ability to add already createdobjects to the container and to remove objects from the containerwithout destroying said objects. The reason for this is that there wasno perceived need for this feature.

[4551] 6. DM_ARR provides the ability to hold references (object IDs,oids) of the contained objects instead of the contained objectsthemselves. The reason for this is that the DriverMagic system does notprovide mechanisms for one object to physically contain the memory ofother objects.

Dynamic Structure Support Factories DM_FAC—Device Driver Factory (WDM)

[4552]FIG. 140 illustrates the boundary of the inventive DM_FAC part forWDM.

[4553] DM_FAC is a generic factory for WDM device drivers includingPlug-n-Play (PnP) drivers. The determination of whether the factory willsupport PnP or not is based on the values set on ext irp and EXT_xxxproperties. If DM_FAC is to handle any PnP-related IRPs, it is assumedthat this is a factory for PnP driver (operates in PnP mode), otherwiseit is not.

[4554] DM_FAC provides the necessary functionality to register thedriver's entry points with Windows and, if necessary, to enumerate andregister the devices controlled by the driver. The device enumeration isnot implemented by DM_FAC—it relies on the part connected to the edevand eprp terminals for this. For each registered device DM_FAC createsand parameterizes a device instance through the array control interfaces(fac and prp).

[4555] For PnP drivers DM_FAC provides the functionality to dynamicallyregister and deregister devices as they appear and disappear from thesystem.

[4556] DM_FAC registers to receive all the basic device I/O requests forthe driver and dispatches them through the dio interface to theappropriate device instance. Depending on the value of its ext_irp andEXT_xxx properties, DM_FAC also registers to receive other I/O requestsand dispatches them to the ext interface.

[4557] Synchronous and asynchronous I/O request completion is providedon both the dio and ext interfaces. Note that DM_FAC allows asynchronouscompletion even for its device factory functionality-IRPs signifyingthat PnP devices have been removed from the system can be completedasynchronously.

[4558] DM_FAC has a notification input through which it is informed ofdriver life-cycle events.

[4559] All outgoing calls on DM_FAC's interfaces are executed in thesame context that Windows I/O Manager used to enter the driver-this iseither a system thread or an application thread and the IRQ level isalways PASSIVE (normal thread context).

[4560] IMPORTANT NOTE: DM_FAC cannot be used to implement drivers thataccept I/O requests at DISPATCH level.

[4561] 1. Boundary

[4562] 1.1. Terminals

[4563] Terminal “drv” with direction “In” and contract I_DRAIN. Note:Life cycle related events.

[4564] Terminal “dio” with direction “Bidir” and contract In: I_DIO Out:I_DIO_C. Note: Device I/O and configuration/status operations. The backchannel can be used for asynchronous completion of operations. DM_FACimplements the dio.complete as an unguarded operation, which can becalled both in thread context (PASSIVE_IRQL) and in dispatch context(DISPATCH_IRQL). dio is a multiplexed output, connectable at activetime.

[4565] Terminal “ext” with direction “Plug” and contract I_DRAIN. Note:IRPs not covered by the I_DIO interface are routed through thisterminal. DM_FAC provides only the IRP pointer to the callee. The backchannel can be used for asynchronous completion of operations. Similarlyto dio, the ext input on DM_FAC is unguarded.

[4566] This terminal may remain unconnected. ext is a multiplexedoutput, connectable at active time.

[4567] Terminal “fac” with direction “Out” and contract I_A_FACT. Note:Part array interface. This terminal is used to create, destroy andenumerate driver instances.

[4568] Terminal “prp” with direction “Out” and contract I_A_PROP. Note:Property interface for part arrays. See below for a list of propertiesthat DM_FAC will set on the created device instances.

[4569] Terminal “edev” with direction “Out” and contract I_DEN. Note:Device enumeration interface. Unless DM_FAC operates in PnP mode, itrequires connection to this terminal to enumerate the devices that haveto be created and registered. Floating.

[4570] Terminal “eprp” with direction “Out” and contract I_A_PROP. Note:This output is used to get extended information for each deviceenumerated through edev. Floating.

[4571] 1.2. Events and Notifications Incoming Event Bus NotesEV_DRV_INIT B_EV_DRV DM_FAC must receive this notification during thedriver ini- tialization. DM_(—) FAC will use this event to register thedriver's entry points, and to enumerate and create the driver objects.EV_DRV_CLEANUP B_EV_DRV DM_FAC must receive this noti- fication beforethe driver is unloaded. EV_IRP_NFY_PROC_CP B_EV_IRP Complete the LT IRPspecified in the event bus.

[4572] 1.3. Special Events, Frames, Commands or Verbs

[4573] None.

[4574] 1.4. Properties

[4575] Property “driver_objectp” of type “UINT32”. Note: Pointer toWindows driver object structure. DM_FAC modifies only the MajorFunctionfield in the driver object. Mandatory.

[4576] Property “ext_irp” of type “UINT32”. Note: A bit mask definingwhich IRP_MJ_xxx functions to pass to the ext terminal. Bits 0 to 31correspond to IRP_MJ_xxx codes 0 to 31 respectively. DM_FAC will ignorebits that correspond to IRPs covered by the I_DIO interface or areoutside the IRP_MJ_MAXIMUM_FUNCTION code (for WDM this is 27 or 0×1 b).DM_FAC will register to receive only those IRP_MJ_xxx calls that havethe corresponding bit set in ext_irp. Default: 0×0.

[4577] Property “EXT_CREATE_NAMED_PIPE” of type “UINT32”. Note: Boolean.Set to TRUE if DM_FAC is to handle this IRP. The value of this propertywill be OR-ed with the respective bit in ext_irp property and the resultwill be used to determine whether DM_FAC will handle a particular IRP ornot. Default: FALSE

[4578] Property “EXT_QUERY_INFORMATION” of type “UINT32”. Note: Same asabove.

[4579] Property “EXT_SET_INFORMATION” of type “UINT32”. Note: Same asabove.

[4580] Property “EXT_QUERY_EA” of type “UINT32”. Note: Same as above.

[4581] Property “EXT_SET_EA” of type “UINT32”. Note: Same as above.

[4582] Property “EXT_FLUSH_BUFFERS” of type “UINT32”. Note: Same asabove.

[4583] Property “EXT_QUERY_VOLUME_INFORMATION” of type “UINT32”. Note:Same as above.

[4584] Property “EXT_SET_VOLUME_INFORMATION” of type “UINT32”. Note:Same as above.

[4585] Property “EXT_DIRECTORY_CONTROL” of type “UINT32”. Note: Same asabove.

[4586] Property “EXT_FILE_SYSTEM_CONTROL” of type “UINT32”. Note: Sameas above.

[4587] Property “EXT_INTERNAL_DEVICE_CONTROL” of type “UINT32”. Note:Same as above.

[4588] Property “EXT_SHUTDOWN ” of type “UINT32”. Note: Same as above.

[4589] Property “EXT_LOCK_CONTROL” of type “UINT32”. Note: Same asabove.

[4590] Property “EXT_CREATE_MAILSLOT” of type “UINT32”. Note: Same asabove.

[4591] Property “EXT_QUERY_SECURITY” of type “UINT32”. Note: Same asabove.

[4592] Property “EXT_SET_SECURITY” of type “UINT32”. Note: Same asabove.

[4593] Property “EXT_POWER” of type “UINT32”. Note: Same as above.

[4594] Property “EXT_SYSTEM_CONTROL” of type “UINT32”. Note: Same asabove.

[4595] Property “EXT_DEVICE_CHANGE” of type “UINT32”. Note: Same asabove.

[4596] Property “EXT_QUERY_QUOTA” of type “UINT32”. Note: Same as above.

[4597] Property “EXT_SET_QUOTA” of type “UINT32”. Note: Same as above.

[4598] Property “EXT_PNP” of type “UINT32”. Note: Same as above.

[4599] Property “EXT_PNP_POWER” of type “UINT32”. Note: Same as above.

[4600] Property “pnp” of type “UINT32”. Note: Boolean. Set to non-zero(TRUE) to indicate that DM_FAC will handle PnP events (IRP_MJ_PNP_xxx).Setting this property to TRUE is equivalent to setting IRP_MJ_PNP andIRP_MJ_PNP_POWER to TRUE or setting the respective bit in ext_irp to 1.When TRUE, DM_FAC ignores the settings of the EXT_PNP and EXT_PNP_POWERproperties (DM_FAC will always handle these IRPs). Default: FALSE

[4601] Property “dflt_class_name” of type “ASCIZ”. Note: The class nameto use when creating device instances, in case the device enumeratordoes not provide a class name. Default: FW_DEV

[4602] Property “mux_dio” of type “UINT32”. Note: Boolean. This propertydefines whether DM_FAC should use the dio interface as a multiplexedoutput or as normal output. If it is set to non-zero, DM_FAC willmultiplex the output using the id returned from the fac interface whendevice instances are created. If this property is 0, DM_FAC willpermanently select the first connection on the dio output and send allcalls to it. Default: TRUE.

[4603] Property “mux_ext” of type “UINT32”. Note: Boolean. This propertydefines whether DM_FAC should use the ext interface as a multiplexedoutput or as normal output. If it is set to non-zero, DM_FAC willmultiplex the output using the id returned from the fac interface whendevice instances are created. If this property is 0, DM_FAC willpermanently select the first connection on the dio output and send allcalls to it. Default: TRUE.

[4604] Property “device_type” of type “UINT32”. Note: Device typeidentifier to use when registering the devices with the operatingsystem. This property is optional—the default value isFILE_DEVICE_UNKNOWN (0×22). Use values between 0×8000 and 0×ffff forcustom-defined types. Note that, although this is not enforced, thedevice type value is normally used in the high-order word (bits 31.16)of the IOCTL codes for this type of device.

[4605] Property “buf_mapping” of type “UINT32”. Note: If set toDIO_MAP_BUFFERED DM_FAC will set DO_BUFFERED_IO flag in the deviceobjects. Default: DIO_MAP_BUFFERED

[4606] Property “force_free” of type “UINT32”. Note: Boolean. If TRUE,DM_FAC will free the self-owned events with no regard what the eventprocessing status is. Default: FALSE

[4607] Property “copy_stkloc” of type “UINT32”. Note: Boolean. If TRUE,DM_FAC will copy the current stack location to the next one (if any)before sending any IRP events through its ext terminal. Default: TRUE

[4608] Property “dev_cls_guidp” of type “UINT32”. Note: Pointer to aGUID identifying the class of devices DM_FAC registers device interfacesfor. For a list of device class GUIDs, consult the Microsoft DDKdocumentation. If NULL, device interfaces will not be registered.Default: NULL

[4609] Property “dev_ref” of type “UNICODEZ”. Note: Reference stringused when registering device interfaces. For description of deviceinterfaces and reference strings, consult the Microsoft DDKdocumentation. Default:

[4610] Property “dev_name_base” of type “UNICODEZ”. Note: Base (prefix)name for symbolic links created for each device. See discussion at theend of this table. If empty string (“”), symbolic link will not beregistered. Default:

[4611] Property “status_xlat” of type “UINT32”. Note: Specifies howDM_FAC translates return statuses that are propagated back up to usermode (Win32). Possible values are 0 (standard NT error codes), 1(standard NT error codes and custom error codes), and 2 (only customerror codes). See the Mechanisms section for more information. Defaultis 0.

[4612] 1.5. Properties Provided by DM_FAC to Device Instances

[4613] The following optional properties are set on the device instancesimmediately after they are created through the fac interface:

[4614] Property “dev_objp” of type “UINT32”. Note: Pointer to the deviceobject that was created for this instance.

[4615] Property “dev_name” of type “ASCIZ”. Note: Device name in kernelmode space. In PnP mode this property is set only if dev_name_baseproperty on DM_FAC is set.

[4616] Property “dev_sym_Ink1” of type “ASCIZ”. Note: Symbolic link #1.In PnP mode this property is set only if dev_name_base property onDM_FAC is set.

[4617] Property “dev_sym_Ink2” of type “ASCIZ”. Note: Symbolic link #2.Not set in PnP mode.

[4618] Property “phys_devp” of type “UINT32”. Note: Pointer to the PDOfor the PnP device being added. Set in PnP mode only.

[4619] Property “low_dev_objp” of type “UINT32”. Note: Pointer to thelower-level driver device object. Set in PnP mode only.

[4620] Property “reg_root” of type “UNICODE”. Note: Path to the device'sRegistry settings. This is provided by the device enumerator connectedto DM_FAC's or the PnP Device Manager on AddDevice.

[4621] 2. Encapsulated Interactions

[4622] DM_FAC uses the following Windows I/O manager API:

[4623] IoAllocateDriverObjectExtension, IoGetDriverObjectExtension

[4624] IoCreateDevice, IoDeleteDevice

[4625] IoAttachDeviceToDeviceStack, IoDetachDevice

[4626] IoRegisterDeviceInterface

[4627] IoGetDeviceProperty

[4628] IoCreateSymbolicLink, IoDeleteSymbolicLink

[4629] IoCompleteRequest

[4630] IoGetCurrentIrpStackLocation, IoCopyCurrentIrpStackLocationToNext

[4631] IoMarkIrpPending

[4632] DM_FAC also provides the entry points to handle IRPs from the I/OManager and modifies the DriverObject structure in order to direct therequests to these entry points.

[4633] 3. Specification

[4634] 4. Responsibilities

[4635] 1. On EV_DRV_INIT: register entry points and if the edev terminalis connected, enumerate devices through it, create and parameterizedevice instances (through fac and prp). If connected, retrieve thefollowing information from the device enumerator:

[4636] class name for the device instance

[4637] Win32 name(s) to associate with the device

[4638] device name (in kernel-mode name space)

[4639] 2. On basic IRP_MJ_xxx calls from I/O Manager (the ones thatmatch operations in I_DIO ): use data from the IRP to fill in the B_DIObus and pass the operation to dio terminal.

[4640] 3. Handle dynamic (PnP) device addition and removal andcreate/destroy device instances for each such device. Provide handlingfor asynchronous completion of the device removal procedure and destroythe instance upon removal.

[4641] 4. For dynamic (PnP) device closure, delay cleanup in case thedevice is still open.

[4642] 5. If an operation on dio returns any status except CMST_PENDING:translate the status to NT status and complete the IRP.

[4643] 6. If an operation on dio returns CMST_PENDING: returnSTATUS_PENDING to Windows without completing the IRP.

[4644] 7. On dio.complete: retrieve the IRP pointer and the completionstatus from B_DIO, translate status to NT status and complete the IRP.

[4645] 8. On IRP_MJ_xxx calls that are not covered by I_DIO-pass thecall to ext as an EV_REQ_IRP event. If the call returns any statusexcept CMST_PENDING—translate return status and complete the IRP.

[4646] 9. On EV_REQ_IRP completion event from ext—translate completionstatus and complete the IRP.

[4647] 10. Translate the return statuses that are propagated back up touser mode according to the status_xlat property.

[4648] 5. Theory of Operation

[4649] 5.1. State Machine

[4650] None

[4651] 5.2. Main Data Structures

DriverObject (system-defined)

[4652] DM_FAC expects to receive a valid pointer to a DriverObjectstructure with the EV_DRV_INIT event. It modifies the MajorFunctionfield in this structure to register its entry points. It also passesthis structure to the Windows I/O Manager when creating deviceinstances.

DeviceObject (system-defined)

[4653] Windows returns a DeviceObject structure when a new device iscreated. DM_FAC uses a public field in this structure (DeviceExtension)to store its per-device context.

IRP (system-defined)

[4654] This structure is used by the I/O Manager to pass requests andtheir arguments for all driver functions (IRP_MJ_xxx).

[4655] 5.3. Mechanisms

Name and Symbolic Link

[4656] In non-PnP mode, the symbollic link to device instances (if any)are provided by the device enumerator connected to the edev terminal. Upto 2 such links can be registered.

[4657] In PnP mode, DM_FAC registers symbolic links (Win32 names) todevice instances using the value of dev_base_name as a prefix andappending to it the value of DevicePropertyDriverKeyName.

[4658] The latter is a persistent identifier of a device. Windowscomputes this identifier the first time a device appears on a particularslot in a particular hardware bus⁴ and remembers it in a persistent partof the registry. DM_FAC will replace any backslash characters (“\”) withdots (“.”), so that this identifier can be used as part of a symboliclink name.

Registry Access

[4659] DM_FAC does not read directly from the Registry.

[4660] In non-PnP mode, a device enumerator connected to the edevterminal is expected to provide registry path for each device. This pathwill be passed as a property (reg_root) to the corresponding deviceinstance created by DM_FAC.

[4661] In PnP mode, the registry root is calculated by the value of

[4662] DevicePropertyDriverKeyName property appended to

[4663] HKLM\System\CurrentControlSet\Services\Class.

Dispatching Operations to Device Instances

[4664] DM_FAC's dio and ext terminals are (independently) multiplexed toallow multiple device instances to be connected to these terminals. Thedefault mechanism for multiplex output selection provided by ClassMagicis not atomic—it requires separate “select” and “call” operations. Thiscannot be used in DM_FAC, because these terminals are not called in aguarded context and may be re-entered from different execution contextssimultaneously.

[4665] DM_FAC does not enter any critical sections while it is callingdio and ext operations to allow the device instances to execute in thesame context in which DM_FAC was entered by I/O Manager. If it isnecessary, the parts that represent the device instances should providetheir own guarding (e.g., the standard part terminal guard provided byClassMagic).

[4666] To overcome this restriction, DM_FAC enters a critical section toperform the multiplex output selection and retrieve a valid v-tableinterface pointer to the selected part. It then calls the operationusing the interface pointer outside of the critical section.

Translating DriverMagic Status Codes

[4667] DM_FAC translates CMST_xxx status codes (that are returned frominvoking operations on the dio and ext terminals—synchronous orasynchronous) into Windows NT status codes or custom status codesdefined by the user. These codes are then propagated up to the user modeenvironment (Win32).

[4668] The status translation is controlled through the status_xlatproperty. This property may have one of the following values:

[4669] 0: Standard NT status codes only (see status table below)

[4670] 1: Standard NT status codes and custom (user-defined) statuscodes

[4671] 2: Custom (user-defined) status codes only

[4672] If translating to standard NT status codes (status_xlat is 0 or1), DM_FAC uses a status table that maps CMST_xxx statuses to NTstatuses. These NT statuses are then converted into Win32 error codes bythe operating system.

[4673] If the CMST_xxx status code is not found in the table, either thestatus is mapped to STATUS_UNSUCCESSFULL (status_xlat is 0) or it ismapped to a custom status (status_xlat is 1) by AN Ding the status codewith 0×E0000000 (this tells the operating system that this is auser-defined status code—the OS will pass the code up to user modewithout modification).

[4674] If status_xlat is 2, the status codes are always user-defined andare ANDed with 0×E0000000 as described above. In this case, DM_FAC doesnot use the table to map the status codes. In user mode, the Win32status code can be ANDed with 0×1FFFFFFF to extract the user-definedstatus code.

[4675] Note that the status codes from Plug-n-Play and power IRPs arealways converted to the proper NT status code without reguard to thestatus_xlat property.

[4676] Below is a table showing the mapping of the DriverMagic statuscodes to NT status codes: DriverMagic Status NT Status CMST_OKERROR_SUCCESS CMST_ALLOC STATUS_NO_MEMORY CMST_NO_ROOMSTATUS_INSUFFICIENT_(—) RESOURCES CMST_OVERFLOW STATUS_BUFFER_TOO_SMALLCMST_UNDERFLOW STATUS_INVALID_(—) PARAMETER CMST_EMPTY STATUS_PIPE_EMPTYCMST_FULL STATUS_DISK_FULL CMST_EOF STATUS_END_OF_FILE CMST_INVALIDSTATUS_INVALID_(—) PARAMETER CMST_BAD_VALUE STATUS_INVALID_(—) PARAMETERCMST_OUT_OF_RANGE STATUS_INVALID_(—) PARAMETER CMST_NULL_PTRSTATUS_INVALID_(—) PARAMETER CMST_BAD_SYNTAX STATUS_INVALID_(—)PARAMETER CMST_BAD_NAME OBJECT_NAME _NVALID CMST_UNEXPECTEDSTATUS_INTERNAL_ERROR CMST_PANIC STATUS_INTERNAL_ERROR CMST_DEADLOCKSTATUS_POSSIBLE_(—) DEADLOCK CMST_STACK_(—) STATUS_BAD_INITIAL_STACKOVERFLOW CMST_REFUSE STATUS_REQUEST_NOT_(—) ACCEPTED CMST_NO_ACTIONSTATUS_REQUEST_NOT_(—) ACCEPTED CMST_FAILED STATUS_UNSUCCESSFULLCMST_NOT_INITED STATUS_INTERNAL_ERROR CMST_NOT_ACTIVESTATUS_INTERNAL_ERROR CMST_NOT_OPEN STATUS_INTERNAL_ERROR CMST_NOT_(—)STATUS_INTERNAL_ERROR CONNECTED CMST NOT_(—) STATUS_INTERNAL_ERRORCONSTRUCTED CMST_IOERR STATUS_10_DEVICE_ERROR CMST_BAD_CHKSUMSTATUS_DEVICE_DATA_(—) ERROR CMST_NOT_FOUND STATUS_NO_SUCH_FILECMST_DUPLICATE STATUS_DUPLICATE_NAME CMST_BUSY STATUS_BUSYCMST_ACCESS_(—) STATUS_ACCESS_DENIED DENIED CMST_PRIVILEGESTATUS_PRIVILEGE_NOT_(—) HELD CMST_SCOPE_(—) STATUS_ACCESS_DENIEDVIOLATION CMST_BAD_ACCESS STATUS_ACCESS_DENIED CMST_PENDINGSTATUS_PENDING CMST_TIMEOUT STATUS_IO_TIMEOUT CMST_CANCELEDSTATUS_CANCELLED CMST_ABORTED STATUS_CANCELLED CMST_RESETSTATUS_CANCELLED CMST_CLEANUP STATUS_CANCELLED CMST_OVERRIDESTATUS_UNSUCCESSFULL CMST_POSTPONE STATUS_UNSUCCESSFULL CMST_CANT_BINDSTATUS_NO_SUCH_FILE CMST_API_ERROR STATUS_NOT_IMPLEMENTED CMST_WRONG_(—)STATUS_REVISION_(—) VERSION MISMATCH CMST_NOT_(—) STATUS_NOT_IMPLEMENTEDIMPLEMENTED CMST_NOT_(—) STATUS_INVALID_DEVICE_(—) SUPPORTED REQUESTCMST_BAD_OID STATUS_INTERNAL_ERROR CMST_BAD_MESSAGESTATUS_INTERNAL_ERROR

[4677] Below is a table showing the mapping of the DriverMagic statuscodes to Win32 (user mode) status codes: DriverMagic Status Win32 StatusCMST_OK NO_ERROR CMST_ALLOC ERROR_NOT_ENOUGH_(—) MEMORY CMST_NO_ROOMERROR_NO_SYSTEM_(—) RESOURCES CMST_OVERFLOW ERROR_INSUFFICIENT_BUFFERCMST_UNDERFLOW ERROR_INVALID_PARAMETER CMST_EMPTY ERROR_NO_DATACMST_FULL ERROR_DISK_FULL CMST_EOF ERROR_HANDLE_EOF CMST_INVALIDERROR_INVALID_PARAMETER CMST_BAD_VALUE ERROR_INVALID_PARAMETERCMST_OUT_OF_RANGE ERROR_INVALID_PARAMETER CMST_NULL_PTRERROR_INVALID_PARAMETER CMST_BAD_SYNTAX ERROR_INVALID_PARAMETERCMST_BAD_NAME ERROR_INVALID_PARAMETER CMST_UNEXPECTEDERROR_INTERNAL_ERROR CMST_PANIC ERROR_INTERNAL_ERROR CMST_DEADLOCKERROR_POSSIBLE_DEADLOCK CMST_STACK_OVERFLOW ERROR_STACK_OVERFLOWCMST_REFUSE ERROR_REQ_NOT_ACCEP CMST_NO_ACTION ERROR_REQ_NOT_ACCEPCMST_FAILED ERROR_GEN_FAILURE CMST_NOT_INITED ERROR_INTERNAL_ERRORCMST_NOT_ACTIVE ERROR_INTERNAL_ERROR CMST_NOT_OPEN ERROR_INTERNAL_ERRORCMST_NOT_CONNECTED ERROR_INTERNAL_ERROR CMST_NOT_CONSTRUCTEDERROR_INTERNAL_ERROR CMST_IOERR ERROR_IO_DEVICE CMST_BAD_CHKSUMERROR_CRC CMST_NOT_FOUND ERROR_FILE_NOT FOUND CMST_DUPLICATEERROR_DUP_NAME CMST_BUSY ERROR_BUSY CMST_ACCESS_DENIEDERROR_ACCESS_DENIED CMST_PRIVILEGE ERROR_PRIVILEGE_NOT_(—) HELDCMST_SCOPE_VIOLATION ERROR_ACCESS_DENIED CMST_BAD_ACCESSERROR_ACCESS_DENIED CMST_PENDING ERROR_IO_PENDING CMST_TIMEOUTERROR_SEM_TIMEOUT CMST_CANCELED ERROR_OPERATION_ABORTED CMST_ABORTEDERROR_OPERATION_ABORTED CMST_RESET ERROR_OPERATION_ABORTED CMST_CLEANUPERROR_OPERATION_ABORTED CMST_OVERRIDE ERROR_GEN_FAILURE CMST_POSTPONEERROR_GEN_FAILURE CMST_CANT_BIND ERROR_FILE_NOT_FOUND CMST_API_ERRORERROR_INVALID_FUNCTION CMST_WRONG_VERSION ERROR_REVISION_MISMATCHCMST_NOT_IMPLEMENTED ERROR_INVALID_FUNCTION CMST_NOT_SUPPORTEDERROR_INVALID_FUNCTION CMST_BAD_OID ERROR_INTERNAL_ERRORCMST_BAD_MESSAGE ERROR_INTERNAL_ERROR

[4678] 5.4. Use Cases

PnP Device Instance Creation

[4679] DM_FAC receives a call from the PnP Device Manager: AddDevice.

[4680] Creates an instance (using default class name) of the partresponsible for the new device through its fac terminal (device part)

[4681] Parameterizes the device part with the arguments of the AddDevice(PDO pointer) and, if eprp is connected with all the properties that thepart connected to this terminal reports (using the devid returned by thefac terminal).

[4682] Attaches the device instance to the device stack and sets thereturned object pointer as a property on the device part.

[4683] Activates the device part.

[4684] Registers symbolic links computing name for the device instancebased on the device id.

PnP Device Instance Destruction (sync.completion)

[4685] DM_FAC receives an IRP_MN_REMOVE_DEVICE.

[4686] Forwards the event out through ext terminal allowing asynchronouscompletion.

[4687] The event completes synchronously.

[4688] Deregisters symbolic links, deactivate, destroys device instanceand returns.

PnP Device Instance Destruction (async.completion)

[4689] DM_FAC receives an IRP_MN_REMOVE_DEVICE.

[4690] Forwards the event out through ext terminal allowing asynchronouscompletion.

[4691] The forwarding completes asynchronously (CMST_PENDING)—returnSTATUS_PENDING.

[4692] When the completion event comes-deregisters symbolic links,deactivate and destroys the instance.

[4693] Completes the IRP.

Synchronous Device I/O Operation

[4694] DM_FAC receives a call from the I/O Manager and translates itinto an I_DIO operation.

[4695] If the mux_dio property is non-zero, it selects the connection onthe dio output (this and the next step are executed as an atomicselect-and-call operation)

[4696] DM_FAC invokes the operation on dio

[4697] The call returns a completion status and DM_FAC translates it toa Windows NT status and completes the IRP sent by the I/O Manager.

Asynchronous Device I/O Operation

[4698] DM_FAC receives a call from the I/O Manager and translates itinto an I_DIO operation.

[4699] If the mux_dio property is non-zero, it selects the connection onthe dio output (this and the next step are executed as an atomicselect-and-call operation)

[4700] DM_FAC invokes the operation on dio

[4701] The call returns CMST_PENDING, which indicates that the operationwill be completed later. DM_FAC marks the IRP as pending and returns toI/O Manager without completing it.

[4702] When the operation is completed, the part connected to dioinvokes the I_DIO_C.complete operation on the back channel of the diointerface using the same bus that was used to start the operation (or acopy of it). DM_FAC retrieves the operation's IRP pointer from the busand reports the completion to the I/O Manager.

[4703] 6. Notes

[4704] The recipient of the IRP_MN_REMOVE_DEVICE IRP event (receivedfrom the ext terminal) must return the removal completion status fromthe lower driver to DM_FAC, not its own removal status. Thus, the returnstatus of the IRP_MN_REMOVE_DEVICE IRP (from DM_FAC) is that of thelower driver.

DM_FAC—Device Driver Factory (NTK)

[4705]FIG. 141 illustrates the boundary of the inventive DM_FAC part forNTK.

[4706] DM_FAC is a generic factory for Windows NT device drivers. Sincethere can be only one driver in a executable, only one instance ofDM_FAC may be created per executable (DM_FAC will enforce this).

[4707] DM_FAC provides the necessary functionality to register thedriver's entry points with Windows NT and to enumerate and register thedevices controlled by the driver. The device enumeration is notimplemented by DM_FAC-it relies on the part connected to the edev andeprp terminals for this. For each registered device DM_FAC creates andparameterizes a device instance through the array control interfaces(fac and prp).

[4708] DM_FAC registers to receive all the basic device I/O requests forthe driver and dispatches them through the dio interface to theappropriate device instance. Depending on the value of its ext_irpproperty, DM_FAC also registers to receive other I/O requests anddispatches them to the ext interface.

[4709] Synchronous and asynchronous I/O request completion is providedon both the dio and ext interfaces.

[4710] DM_FAC has a notification input through which it is informed oflife-cycle related driver events.

[4711] All outgoing calls on DM_FAC's interfaces are executed in thesame context that Windows NT I/O Manager used to enter the driver-thisis either a system thread or an application thread and the IRQ level isalways PASSIVE (normal thread context).

[4712] 7. Boundary

[4713] 7.1. Terminals

[4714] Terminal “drv” with direction “In” and contract I_DRAIN. Note:Life cycle related events.

[4715] Terminal “dio” with direction “Bidir” and contract In: I DIO Out:I_DIO_C. Note: Device I/O and config/status operations. The back channelcan be used for asynchronous completion of operations. DM_FAC implementsthe dio.complete as an unguarded operation, which can be called both inthread context (PASSIVE_IROL) and in dispatch context (DISPATCH_IRQL).dio is a multiplexed output, connectable at active time.

[4716] Terminal “ext” with direction “Plug” and contract I_DRAIN. Note:IRPs not covered by the I_DIO interface are routed through thisterminal. DM_FAC provides only the IRP pointer to the callee. The backchannel can be used for asynchronous completion of operations. Similarlyto dio, the ext input on DM_FAC is unguarded. This terminal may remainunconnected. ext is a multiplexed output, connectable at active time.

[4717] Terminal “fac” with direction “Out” and contract I_A_FACT. Note:Part array interface. This terminal is used to create, destroy andenumerate driver instances.

[4718] Terminal “prp” with direction “Out” and contract I_A_PROP. Note:Property interface for part arrays. See below for a list of propertiesthat DM_FAC will set on the created device instances.

[4719] Terminal “edev” with direction “Out” and contract I_DEN. Note:Device enumeration interface. DM_FAC requires this connection toenumerate the devices that have to be created and registered.

[4720] Terminal “eprp” with direction “Out” and contract I_A_PROP. Note:This output is 5 used in conjunction with edev to get extendedinformation for each device enumerated through edev.

[4721] 7.2. Events and Notifications Incoming Event Bus NotesEV_DRV_INIT B_EV_(—) DM_FAC must receive this DRV notification duringthe driver initialization. DM_FAC will use this event to register thedriver's entry points, and to enumerate and create the driver objects.EV_DRV_(—) B_EV_(—) DM_FAC must receive this CLEANUP DRV notificationbefore the driver is unloaded. EV_IRP_NFY_(—) B_EV_IRP Complete the IRPspecified PROC_CPLT in the event bus.

[4722] 7.3. Special Events, Frames, Commands or Verbs

[4723] None.

[4724] 7.4. Properties

[4725] Property “driver_objectp” of type “UINT32”. Note: Pointer toWindows NT driver object structure. DM_FAC modifies only theMajorFunction field in the driver object. This property is mandatory.

[4726] Property “ext_irp” of type “UINT32”. Note: A bit mask definingwhich IRP_MJ_xxx functions to pass to the ext terminal. Bits 0 to 31correspond to IRP_MJ_xxx codes 0 to 31 respectively. DM_FAC will ignorebits that correspond to IRPs covered by the I_DIO interface or areoutside the IRP_MJ_MAXIMUM_FUNCTION code (for Windows NT 4.0 this is 27or 0×1 b). DM_FAC will register to receive only those IRP_MJ_xxx callsthat have the corresponding bit set in ext_irp. The default value forext_irp is 0.

[4727] Property “dflt_class_name” of type “ASCIZ”. Note: The class nameto use when creating device instances, in case the device enumeratordoes not provide a class name. The default value for this property is“FW_DEV”.

[4728] Property “multiplex” of type “UINT32”. Note: This propertydefines whether DM_FAC should use the dio and ext interfaces asmultiplexed outputs or as normal outputs. If it is set to non-zero,DM_FAC will multiplex the outputs using the id returned from the facinterface when device instances are created. If this property is 0,DM_FAC will permanently select the first connection on the dio and extoutputs and send all calls to it. The default value for multiplex is 1(TRUE).

[4729] Property “device_type” of type “UINT32”. Note: Device typeidentifier to use when registering the devices with the operatingsystem. This property is optional-the default value isFILE_DEVICE_UNKNOWN (0×22). Use values between 0×8000 and 0×ffff forcustom-defined types. Note that, although this is not enforced, thedevice type value is normally used in the high-order word (bits 31.16)of the IOCTL codes for this type of device.

[4730] Property “status_xlat” of type “UINT32”. Note: Specifies howDM_FAC translates return statuses that are propagated back up to usermode (Win32). Possible values are 0 (standard NT error codes), 1(standard NT error codes and custom error codes), and 2 (only customerror codes). See the Mechanisms section for more information. Defaultis 0.

[4731] 7.5. Registry Access

[4732] DM_FAC does not read directly from the Registry. The deviceenumerator connected to the edev terminal is expected to provide aregistry path for each device. This path will be passed as a property(reg_root) to the corresponding device instance created by DM_FAC.

[4733] 7.6. Properties Provided by DM_FAC to Device Instances

[4734] The following optional properties are set on the device instancesimmediately after they are created through the fac interface:

[4735] Property “device_objectp” of type “UINT32”. Note: Pointer to thedevice object that was created for this instance.

[4736] Property “reg_root” of type “UNICODE”. Note: Path to the device'sRegistry settings. This value is provided by the device enumeratorconnected to DM_FAC's edev and eprp outputs.

[4737] 8. Encapsulated Interactions

[4738] DM_FAC calls the Windows NT I/O manager to register devices(IoCreateDevice) and to register Win32-accessible aliases for thedevices (IoCreateSymbolicLink).

[4739] DM_FAC also provides the entry points to handle IRPs from the I/OManager and modifies the DriverObject structure in order to direct therequests to these entry points.

[4740] 9. Specification

[4741] 10. Responsibilities

[4742] On EV_DRV_INIT: register entry points, enumerate devices throughedev, and create and parameterize device instances (through fac andprp). Retrieve the following information from the device enumerator:

[4743] class name for the device instance

[4744] Win32 name(s) to associate with the device

[4745] device name (in kernel-mode name space)

[4746] On basic IRP_MJ_xxx calls from I/O Manager (the ones that matchoperations in I_DIO): use data from the IRP to fill in the B_DIO bus andpass the operation to dio terminal.

[4747] If an operation on dio returns any status except CMST_PENDING:translate the status to NT status and complete the IRP.

[4748] If an operation on dio returns CMST_PENDING: returnSTATUS_PENDING to Windows NT without completing the IRP.

[4749] On dio.complete: retrieve the IRP pointer and the completionstatus from B_DIO, translate status to NT status and complete the IRP.

[4750] On IRP_MJ_xxx calls that are not covered by I_DIO—pass the callto ext as an EV_IRP_REQ_PROCESS event. If the call returns any statusexcept CMST_PENDING-translate return status and complete the IRP.

[4751] On EV_IRP_NFY_PROC_CPLT event from ext-translate completionstatus and complete the IRP.

[4752] Translate the return statuses that are propagated back up to usermode according to the status_xlat property.

[4753] 11. Theory of Operation

[4754] 11. 1. State Machine

[4755] None

[4756] 11.2. Main Data Structures

DriverObject (system-defined)

[4757] DM_FAC expects to receive a valid pointer to a DriverObjectstructure with the EV_DRV_INIT event. It modifies the MajorFunctionfield in this structure to register its entry points. It also passesthis structure to the Windows NT I/O Manager when creating deviceinstances.

DeviceObject(system-defined)

[4758] A DeviceObject structure is returned by Windows NT when a newdevice is created. DM_FAC uses a public field in this structure(DeviceExtension) to store its per-device context.

IRP (system-defined)

[4759] This structure is used by the I/O Manager to pass the argumentsfor all driver functions (IRP_MJ_xxx).

[4760] 11.3. Mechanisms

Dispatching Operations to Device Instances

[4761] DM_FAC's dio and ext terminals are multiplexed to allow multipledevice instances to be connected to these terminals. The defaultmechanism for multiplex output selection provided by ClassMagic is notatomic—it requires separate “select” and “call” operations. This cannotbe used in DM_FAC, because these terminals are not called in a guardedcontext and may be re-entered from different execution contextssimultaneously.

[4762] DM_FAC should not enter any critical sections while it is callingdio and ext operations to allow the device instances to execute in thesame context in which DM_FAC was entered by I/O Manager. If it isnecessary, the parts that represent the device instances may providetheir own guarding (e.g., the standard part terminal guard provided byClassMagic).

[4763] To overcome this restriction, DM_FAC enters a critical section toperform the multiplex output selection and retrieve a valid v-tableinterface pointer to the selected part. It then calls the operationusing the interface pointer outside of the critical section.

Translating DriverMagic Status Codes

[4764] DM_FAC translates CMST_xxx status codes (that are returned frominvoking operations on the dio and ext terminals-synchronous orasynchronous) into Windows NT status codes or custom status codesdefined by the user. These codes are then propagated up to the user modeenvironment (Win32).

[4765] The status translation is controlled through the status_xlatproperty. This property may have one of the following values:

[4766] 0: Standard NT status codes only (see status table below)

[4767] 1: Standard NT status codes and custom (user-defined) statuscodes

[4768] 2: Custom (user-defined) status codes only

[4769] If translating to standard NT status codes (status_xlat is 0 or1), DM_FAC uses a status table that maps CMST_xxx statuses to NTstatuses. These NT statuses are then converted into Win32 error codes bythe operating system.

[4770] If the CMST_xxx status code is not found in the table, either thestatus is mapped to STATUS_UNSUCCESSFULL (status_xlat is 0) or it ismapped to a custom status (status_xlat is 1) by ANDing the status codewith 0×E0000000 (this tells the operating system that this is auser-defined status code—the OS will pass the code up to user modewithout modification).

[4771] If status_xlat is 2, the status codes are always user-defined andare ANDed with 0×E0000000 as described above. In this case, DM_FAC doesnot use the table to map the status codes. In user mode, the Win32status code can be ANDed with 0×1FFFFFFF to extract the user-definedstatus code.

[4772] Below is a table showing the mapping of the DriverMagic statuscodes to NT status codes: DriverMagic Status NT Status CMST_OKERROR_SUCCESS CMST_ALLOC STATUS_NO_MEMORY CMST_NO_ROOMSTATUS_INSUFFICIENT_(—) RESOURCES CMST_OVERFLOW STATUS_BUFFER_TOO_SMALLCMST_UNDERFLOW STATUS_INVALID_(—) PARAMETER CMST_EMPTY STATUS_PIPE_EMPTYCMST_FULL STATUS_DISK_FULL CMST_EOF STATUS_END_OF_FILE CMST_INVALIDSTATUS_INVALID_(—) PARAMETER CMST_BAD_VALUE STATUS_INVALID_(—) PARAMETERCMST_OUT_OF_RANGE STATUS_INVALID_(—) PARAMETER CMST_NULL_PTRSTATUS_INVALID_(—) PARAMETER CMST_BAD_SYNTAX STATUS_INVALID_(—)PARAMETER CMST_BAD_NAME OBJECT_NAME_INVALID CMST_UNEXPECTEDSTATUS_INTERNAL_ERROR CMST_PANIC STATUS_INTERNAL_ERROR CMST_DEADLOCKSTATUS_POSSIBLE_(—) DEADLOCK CMST_STACK_OVERFLOWSTATUS_BAD_INITIAL_STACK CMST_REFUSE STATUS_REQUEST_NOT_(—) ACCEPTEDCMST_NO_ACTION STATUS_REQUEST_NOT_(—) ACCEPTED CMST_FAILEDSTATUS_UNSUCCESSFULL CMST_NOT_INITED STATUS_INTERNAL_ERRORCMST_NOT_ACTIVE STATUS_INTERNAL_ERROR CMST_NOT_OPENSTATUS_INTERNAL_ERROR CMST_NOT_CONNECTED STATUS_INTERNAL_ERRORCMST_NOT_CONSTRUCTED STATUS_INTERNAL_ERROR CMST_IOERRSTATUS_IO_DEVICE_ERROR CMST_BAD_CHKSUM STATUS_DEVICE_DATA_(—) ERRORCMST_NOT_FOUND STATUS_NO_SUCH_FILE CMST_DUPLICATE STATUS_DUPLICATE_NAMECMST_BUSY STATUS_BUSY CMST_ACCESS_DENIED STATUS_ACCESS_DENIEDCMST_PRIVILEGE STATUS_PRIVILEGE_NOT_(—) HELD CMST_SCOPE_VIOLATIONSTATUS_ACCESS_DENIED CMST_BAD_ACCESS STATUS_ACCESS_DENIED CMST_PENDINGSTATUS_PENDING CMST_TIMEOUT STATUS_IO_TIMEOUT CMST_CANCELEDSTATUS_CANCELLED CMST_ABORTED STATUS_CANCELLED CMST_RESETSTATUS_CANCELLED CMST_CLEANUP STATUS_CANCELLED CMST_OVERRIDESTATUS_UNSUCCESSFULL CMST_POSTPONE STATUS_UNSUCCESSFULL CMST_CANT_BINDSTATUS_NO_SUCH_FILE CMST_API_ERROR STATUS_NOT_IMPLEMENTEDCMST_WRONG_VERSION STATUS_REVISION_MISMATCH CMST_NOT_IMPLEMENTEDSTATUS_NOT_IMPLEMENTED CMST_NOT_SUPPORTED STATUS_INVALID_DEVICE_(—)REQUEST CMST_BAD_OID STATUS_INTERNAL_ERROR CMST_BAD_MESSAGESTATUS_INTERNAL_ERROR

[4773] Below is a table showing the mapping of the DriverMagic statuscodes to Win32 (user mode) status codes: DriverMagic Status Win32 StatusCMST_OK NO_ERROR CMST_ALLOC ERROR_NOT_ENOUGH_(—) MEMORY CMST_NO_ROOMERROR_NO_SYSTEM_(—) RESOURCES CMST_OVERFLOW ERROR_INSUFFICIENT_BUFFERCMST_UNDERFLOW ERROR_INVALID_PARAMETER CMST_EMPTY ERROR_NO_DATACMST_FULL ERROR_DISK_FULL CMST_EOF ERROR_HANDLE_EOF CMST_INVALIDERROR_INVALID_PARAMETER CMST_BAD_VALUE ERROR_INVALID_PARAMETERCMST_OUT_OF_RANGE ERROR_INVALID_PARAMETER CMST_NULL_PTRERROR_INVALID_PARAMETER CMST_BAD_SYNTAX ERROR_INVALID_PARAMETERCMST_BAD_NAME ERROR_INVALID_PARAMETER CMST_UNEXPECTEDERROR_INTERNAL_ERROR CMST_PANIC ERROR_INTERNAL_ERROR CMST_DEADLOCKERROR_POSSIBLE_DEADLOCK CMST_STACK_OVERFLOW ERROR_STACK_OVERFLOWCMST_REFUSE ERROR_REQ_NOT_ACCEP CMST_NO_ACTION ERROR_REQ_NOT_ACCEPCMST_FAILED ERROR_GEN_FAILURE CMST_NOT_INITED ERROR_INTERNAL_ERRORCMST_NOT_ACTIVE ERROR_INTERNAL_ERROR CMST_NOT_OPEN ERROR_INTERNAL_ERRORCMST_NOT_CONNECTED ERROR_INTERNAL_ERROR CMST_NOT_CONSTRUCTEDERROR_INTERNAL_ERROR CMST_IOERR ERROR_IO_DEVICE CMST_BAD_CHKSUMERROR_CRC CMST_NOT_FOUND ERROR_FILE_NOT_FOUND CMST_DUPLICATEERROR_DUP_NAME CMST_BUSY ERROR_BUSY CMST_ACCESS_DENIEDERROR_ACCESS_DENIED CMST_PRIVILEGE ERROR_PRIVILEGE_NOT_(—) HELDCMST_SCOPE_VIOLATION ERROR_ACCESS_DENIED CMST_BAD_ACCESSERROR_ACCESS_DENIED CMST_PENDING ERROR_IO_PENDING CMST_TIMEOUTERROR_SEM_TIMEOUT CMST_CANCELED ERROR_OPERATION_ABORTED CMST_ABORTEDERROR_OPERATION_ABORTED CMST_RESET ERROR_OPERATION_ABORTED CMST_CLEANUPERROR_OPERATION_ABORTED CMST_OVERRIDE ERROR_GEN_FAILURE CMST_POSTPONEERROR_GEN_FAILURE CMST_CANT_BIND ERROR_FILE_NOT_FOUND CMST_API_ERRORERROR_INVALID_FUNCTION CMST_WRONG_VERSION ERROR_REVISION_MISMATCHCMST_NOT_IMPLEMENTED ERROR_INVALID_FUNCTION CMST_NOT_SUPPORTEDERROR_INVALID_FUNCTION CMST_BAD_OID ERROR_INTERNAL_ERRORCMST_BAD_MESSAGE ERROR_INTERNAL_ERROR

[4774] 11.4. Use Cases

Synchronous I/O Operation

[4775] DM_FAC receives a call from the I/O Manager and translates itinto an I_DIO operation.

[4776] If the multiplex property is non-zero, it selects the connectionon the dio output (this and the next step are executed as an atomicselect-and-call operation)

[4777] DM_FAC invokes the operation on dio

[4778] The call returns a completion status and DM_FAC translates it toa Windows NT status and completes the IRP sent by the I/O Manager.

Asynchronous I/O Operation

[4779] DM_FAC receives a call from the I/O Manager and translates itinto an I_DIO operation.

[4780] If the multiplex property is non-zero, it selects the connectionon the dio output (this and the next step are executed as an atomicselect-and-call operation)

[4781] DM_FAC invokes the operation on dio

[4782] The call returns CMST_PENDING, which indicates that the operationwill be completed later. DM_FAC marks the IRP as pending and returns toI/O Manager without completing it.

[4783] When the operation is completed, the part connected to dioinvokes the I_DIO_C.complete operation on the back channel of the diointerface using the same bus that was used to start the operation (or acopy of it). DM_FAC retrieves the operation's IRP pointer from the busand reports the completion to the I/O Manager.

DM_VXFAC—VxD Device Driver Factory

[4784]FIG. 142 illustrates the boundary of the inventive DM_VXFAC part.

[4785] DM_VXFAC is a generic factory for Windows 95/98 VxD devicedrivers.

[4786] DM_VXFAC translates VxD life-cycle and device I/O control eventsreceived on its drv terminal into I_DIO operations that are passed outthrough the dio terminal.

[4787] On driver initialization, DM_VXFAC creates and parameterizes onedevice instance through the array control interfaces (fac and prp).Typically the device instance receives the dio operation calls generatedby DM_VXFAC.

[4788] Since there are no specific read and write operations for VxDs,DM_VXFAC allows read and write I/O controls to be defined for a device(specified through properties). When these I/O controls are received byDM_VXFAC, they are translated into dio.read and dio.write operations.All other I/O controls are translated to dio.ioctl.

[4789] All dio operations generated by DM_VXFAC may be completedsynchronously or asynchronously. DM_VXFAC takes care of the properoperation re-synchronization and completion.

[4790] 12. Boundary

[4791] 12.1. Terminals

[4792] Terminal “drv” with direction “In” and contract I_DRAIN. Note:Synchronous, vtable, infinite cardinality, unguarded Life cycle and I/Ocontrol VxD events are received through this terminal. The life cycleand I/O control events received here are converted into I_DIO operationssent out through the dio terminal. This terminal is compatible with theVxD package events defined in e_vxd.h.

[4793] Terminal “dio” with direction “Bidir” and contract In: I_DIO_COut: I_DIO . Note: Synchronous, vtable, cardinality 1, unguarded,activetime Device I/O operations. DM_VXFAC converts life cycle and I/Ocontrol events received from the drv terminal into I_DIO operations sentout through this terminal. The back channel is used for asynchronouscompletion of operations (as defined by the I_DIO interface).

[4794] Terminal “fac” with direction “Out” and contract I_A_FACT. Note:Synchronous, vtable, cardinality 1 Part array factory interface. Thisterminal is used to create, activate, deactivate and destroy a deviceinstance. DM_VXFAC creates only one device instance.

[4795] Terminal “prp” with direction “Out” and contract I_A_PROP. Note:Synchronous, vtable, cardinality 1 Part array property interface formanipulating properties of device instances. See below for a list ofproperties that DM VXFAC sets on the created device instances.

[4796] 12.2. Events and Notifications Incoming Event Bus NotesEV_VXD_(—) B_EV_(—) VxD initialization event. INIT VXD DM_VXFAC mustreceive this notification during the driver initialization. DM_(—) VXFACuses this event to create, parameterize and activate the device instanceassembly. Typically, this event is sent by the driver packaging.EV_VXD_(—) B_EV_(—) VxD cleanup event. CLEANUP VXD DM_VXFAC must receivethis notification before the driver is unloaded. DM_VXFAC uses thisevent to deactivate and destroy the device instance assembly. Typically,this event is sent by the driver packaging. EV_VXD_(—) B_EV_(—) VxD lifecycle and I/O control event. MESSAGE VXD When the W32_DEVICEIOCONTROLmessage is received, DM_VXFAC translates the open/close requests(DIOC_OPEN and DIOC_(—) CLOSEHANDLE) and I/O controls into I_DIOoperations that are passed through the dio terminal. DM_VXFAC isparameterized with the I/O controls that represent read and writeoperations on the device. All other I/O controls are translated intodio.ioctl. Typically, this event is sent by the driver packaging.

[4797] 12.3. Special Events, Frames, Commands or Verbs

[4798] None.

[4799] 12.4. Properties

[4800] Property “dflt_class_name” of type “ASCIZ”. Note: Default classname of the device instance assembly. This is the class name to use whencreating device instances. DM_VXFAC creates the instance when itreceives an EV_VXD_INIT event on the drv terminal. DM_VXFAC only usesthis property if the class_name property is empty (“”). This property isprovided for compatibility with the Windows NT factory (DM_FAC). Defaultvalue is “FW_DEV”.

[4801] Property “class_name” of type “ASCIZ”. Note: Class name of thedevice instance assembly. This is the class name to use when creatingdevice instances. DM_VXFAC creates the instance when it receives anEV_VXD_INIT event on the drv terminal. If this property is not equal to“”, DM_VXFAC always uses this class name for the device instance.Default value is “” (dflt_class_name is used).

[4802] Property “status_xlat” of type “UINT32”. Note: Specifies howDM_VXFAC translates return statuses that are propagated back up to usermode (Win32). Possible values are 0 (standard Win32 error codes), 1(standard Win32 error codes and custom error codes), 2 (custom errorcodes only) and 3 (always return success). See the Mechanisms sectionfor more information. Default value is 0.

[4803] Property “ioctl_read” of type “UINT32”. Note: I/O control codefor read operations. When this I/O control code is received by DM_VXFAC,it converts it into an dio.read operation. Default value is 0 (none).

[4804] Property “ioctl_write” of type “UINT32”. Note: I/O control codefor write operations. When this I/O control code is received byDM_VXFAC, it converts it into an dio.write operation. Default value is 0(none).

[4805] Property “ioctl_stat offs” of type “UINT32”. Note: Operationcompletion status offset. This is the offset (in bytes) into the I/Ocontrol data block where the operation's completion status is stored. If−1, DM_VXFAC does not copy the completion status for the operation intothe I/O control data block. The size of the storage for the completionstatus is 4 bytes (unsigned long). Default value is 0 (first field indata block).

[4806] Property “cplt_wait_type” of type “UINT32”. Note: Asynchronouscompletion semaphore flags. These flags control what actions to takewhen interrupts occur while DM_VXFAC is waiting for an asynchronousopen/cleanup/close operation to complete. Default is BLOCK_THREAD_IDLE.

[4807] Property “reg_root” of type “ASCIZ”. Note: Registry root path.This is the registry path for the devices registry settings. This pathis relative to HKEY_LOCAL_MACHINE. Default value is “”.

[4808] 12.5. Properties Provided by DM_VXFAC to Device Instances

[4809] The following optional properties are set on the device instanceimmediately after it is created through the fac terminal:

[4810] Property “reg_root” of type “ASCIZ”. Note: Path to the device'sregistry settings. DM_VXFAC gets the value for this property from itsreg_root property (pass-through property). This path is relative toHKEY_LOCAL_MACHINE.

[4811] 13. Encapsulated Interactions

[4812] DM_VXFAC uses the following APIs from VtoolsD for asynchronousoperation completion, mutex and semaphore usage:

[4813] VWIN32_DIOCCompletionRoutine( )

[4814] CreateMutex( )

[4815] DestroyMutex( )

[4816] EnterMutex( )

[4817] LeaveMutex( )

[4818] Create_Semaphore( )

[4819] Destroy_Semaphore( )

[4820] Wait_Semaphore( )

[4821] Signal_Semaphore_No_Switch( )

[4822] LinPageLock( )

[4823] LinePageUnlock( )

[4824] 14. Specification

[4825] 15. Responsibilities

[4826] On EV_VXD_INIT: create, parameterize and activate a single deviceinstance (through the fac and prp terminals). Create only one deviceinstance.

[4827] On EV_VXD_CLEANUP: deactivate and destroy the device instance(through the fac terminal).

[4828] On DIOC_OPEN control message (EV_VXD_MESSAGE): generate adio.open operation call. If operation completes asynchronously (returnsCMST_PENDING), wait on a semaphore until the operation is complete.

[4829] 12.5. Properties Provided by DM_VXFAC to Device Instances

[4830] The following optional properties are set on the device instanceimmediately after it is created through the fac terminal:

[4831] Property “reg_root” of type “ASCIZ”. Note: Path to the device'sregistry settings. DM_VXFAC gets the value for this property from itsreg_root property (pass-through property). This path is relative toHKEY_LOCAL_MACHINE.

[4832] 13. Encapsulated Interactions

[4833] DM_VXFAC uses the following APIs from VtoolsD for asynchronousoperation completion, mutex and semaphore usage:

[4834] VWIN32DIOCCompletionRoutine( )

[4835] CreateMutex( )

[4836] DestroyMutex( )

[4837] EnterMutex( )

[4838] LeaveMutex( )

[4839] Create_Semaphore( )

[4840] Destroy_Semaphore( )

[4841] Wait_Semaphore( )

[4842] Signal_Semaphore_No_Switch( )

[4843] LinPageLock( )

[4844] LinePageUnlock( )

[4845] 14. Specification

[4846] 15. Responsibilities

[4847] On EV_VXD_INIT: create, parameterize and activate a single deviceinstance (through the fac and prp terminals). Create only one deviceinstance.

[4848] On EV_VXD_CLEANUP: deactivate and destroy the device instance(through the fac terminal).

[4849] On DIOC_OPEN control message (EV_VXD_MESSAGE): generate adio.open operation call. If operation completes asynchronously (returnsCMST_PENDING), wait on a semaphore until the operation is complete.

[4850] On DIOC_CLOSEHANDLE control message (EV_VXD_MESSAGE): generatedio.cleanup and dio.close operation calls. If operations areasynchronous (return CMST_PENDING) wait on a semaphore until theoperations complete.

[4851] When the read or write I/O control is received (through theEV_VXD_MESSAGE event), generate dio.read and dio.write operationsrespectively.

[4852] On all I/O controls other then DIOC_OPEN, DIOC_CLOSEHANDLE, reador write; generate a dio.ioctl operation.

[4853] Allow asynchronous completion of all I_DIO operations.

[4854] On dio.complete: retrieve the completion status from B_DIO,translate the completion status and complete the operation.

[4855] Translate the completion status for both synchronous andasynchronous operations according to the status_xlat property.

[4856] Handle all unrecognized control messages received on drv (allexcept W32_DEVICEIOCONTROL) by returning CMST_NOT_SUPPORTED withoutentering any critical sections or enabling interrupts.

[4857] 16. Theory of Operation

[4858] 16.1. Main Data Structures

DIGOCParams (system-defined)

[4859] DM_VXFAC expects to receive a valid pointer to a DIOCParamsstructure with the EV_VXD_MESSAGE event, W32_DEVICEIOCONTROL message. Itcopies most of the fields of this structure to a B_DIO bus passed withthe corresponding I_DIO operation. Upon operation completion, DM_VXFACfills in the number of bytes returned in the output buffer(IpcbBytesReturned field).

OVERLAPPED (system-defined)

[4860] DM_VXFAC expects to receive a valid pointer to an OVERLAPPEDstructure with the EV_VXD_MESSAGE event, W32_DEVICEIOCONTROL message fordevices using overlapped I/O. The Win32 event contained in thisstructure is signaled by the operating system when a pending operationhas completed. Win32 API. The application is expected to pass a pointerto the following structure as the input and output buffers for the I/Ocontrol: typedef struct XXX { unsigned long cplt_s ; // IOCTL completionstatus unsigned long reserved ; // reserved for internal use //additional I/O control data here } XXX; // nb: no equivalentfunctionality is provided by the Windows // NT device driver factory.

[4861] The first two fields must be the completion status and a reservedfield. Additional fields may be added depending on the operation of theI/O control.

[4862] The cplt_s field is used to store the operation completionstatus. For asynchronous operations (Overlapped I/O), DM_VXFAC returnspending status (DeviceIOControl( ) returns FALSE and GetLastError()==ERROR IO PENDING). When the operation completes, DM_VXFAC copies theoperation completion status into the I/O control structure.

[4863] When DM_VXFAC receives the I/O control, it checks if the I/Ocontrol code is equal to ioctl_read or ioctl_write. If so, DM_VXFACgenerates dio.read and dio.write operations respectively. All other I/Ocontrols are translated into dio.ioctl operations.

[4864] I/O control operations may be processed synchronously orasynchronously.

[4865] For synchronous and asynchronous operations, DM_VXFAC alwaysupdates the cplt_s field with the completion status of the operation(if_ioctl_stat_offs !=−1). This allows a driver to fail an asynchronousoperation; the application checks the cplt_s field for the completionstatus.

Translating DriverMagic Status Codes

[4866] DM_VXFAC translates CMST_xxx status codes (that are returned frominvoking operations on the dio terminal-synchronous or asynchronous)into Win32 status codes or custom status codes defined by the user.These codes are then propagated up to the user mode environment (Win32).

[4867] The status translation is controlled through the status_xlatproperty. This property may have one of the following values:

[4868] 0: Standard Win32 status codes only (see status table below)

[4869] 1: Standard Win32 status codes and custom status codes

[4870] 2: Custom (user-defined) status codes only

[4871] 3: Success status always

[4872] If translating to standard Win32 status codes (status_xlat is 0or 1), DM_VXFAC uses a status table that maps CMST_xxx statuses to Win32statuses.

[4873] If the CMST_xxx status code is not found in the table, either thestatus is mapped to ERROR_GEN_FAILURE (status_xlat is 0) or it is mappedto a custom status (status_xlat is 1) by ORing the status code with0×E0000000 (this tells the operating system that this is a user-definedstatus code—the operating system passes the code up to user mode withoutmodification).

[4874] If status_xlat is 2, the status codes are always user-defined andare ORed with 0×E0000000 as described above. In this case, DM_VXFAC doesnot use the table to map the status codes. In user mode, the Win32status code can be ANDed with 0×1FFFFFFF to extract the user-definedstatus code.

[4875] If status_xlat is 3, DM_VXFAC always returns success (NO_ERROR)for the operation. A Win32 application can check the status code bychecking the completion status in the operation bus (cplt_s). This fieldwill always contain the status returned by the operation ORed with0×E0000000. This type of status translation is provided since there isno way to return errors for asynchronous operations.

[4876] Note that the status translation does not apply to DIOC_OPEN andDIOC_CLOSEHANDLE.

[4877] Below is a table showing the mapping of the DriverMagic statuscodes to Win32 (user mode) status codes: DriverMagic Status Win32 StatusCMST_OK NO_ERROR CMST_ALLOC ERROR_NOT_ENOUGH_MEMOR Y CMST_NO_ROOMERROR_NO_SYSTEM_RESOUR CES CMST_OVERFLOW ERROR_INSUFFICIENT_BUFFERCMST_UNDERFLOW ERROR_INVALID_PARAMETER CMST_EMPTY ERROR_NO_DATACMST_FULL ERROR_DISK_FULL CMST_EOF ERROR_HANDLE_EOF CMST_INVALIDERROR_INVALID_PARAMETER CMST_BAD_VALUE ERROR_INVALID_PARAMETERCMST_OUT_OF_RANGE ERROR_INVALID PARAMETER CMST_NULL_PTRERROR_INVALID_PARAMETER CMST_BAD_SYNTAX ERROR_INVALID_PARAMETERCMST_BAD_NAME ERROR_INVALID_PARAMETER CMST_UNEXPECTEDERROR_INTERNAL_ERROR CMST_PANIC ERROR_INTERNAL_ERROR CMST_DEADLOCKERROR_POSSIBLE_DEADLOCK CMST_STACK_OVERFL ERROR_STACK_OVERFLOW OWCMST_REFUSE ERROR_REQ_NOT_ACCEP CMST_NO_ACTION ERROR_REQ_NOT_ACCEPCMST_FAILED ERROR_GEN_FAILURE CMST_NOT_INITED ERROR_INTERNAL_ERRORCMST_NOT_ACTIVE ERROR_INTERNAL_ERROR CMST_NOT_OPEN ERROR_INTERNAL_ERRORCMST_NOT_CONNECT ERROR_INTERNAL_ERROR ED CMST_NOT CONSTRUERROR_INTERNAL_ERROR CTED CMST_IOERR ERROR_IO_DEVICE CMST_BAD_CHKSUMERROR_CRC CMST_NOT_FOUND ERROR_FILE_NOT_FOUND CMST_DUPLICATEERROR_DUP_NAME CMST_BUSY ERROR_BUSY CMST_ACCESS_DENIEERROR_ACCESS_DENIED D CMST_PRIVILEGE ERROR_PRIVILEGE_NOT_HELDCMST_SCOPE_VIOLATI ERROR_ACCESS_DENIED ON CMST_BAD_ACCESSERROR_ACCESS_DENIED CMST_PENDING ERROR_IO_PENDING CMST_TIMEOUTERROR_SEM_TIMEOUT CMST_CANCELED ERROR_OPERATION_ABORTED CMST_ABORTEDERROR_OPERATION_ABORTED CMST_RESET ERROR_OPERATION_ABORTED CMST_CLEANUPERROR_OPERATION_ABORTED CMST_OVERRIDE ERROR_GEN_FAILURE CMST_POSTPONEERROR_GEN_FAILURE CMST_CANT_BIND ERROR_FILE_NOT_FOUND CMST_API_ERRORERROR_INVALID_FUNCTION CMST_WRONG_VERSI ERROR_REVISION_MISMATCH ONCMST_NOT_IMPLEMEN ERROR_INVALID_FUNCTION TED CMST_NOT_SUPPORTEERROR_INVALID_FUNCTION D CMST_BAD_OID ERROR_INTERNAL_ERRORCMST_BAD_MESSAGE ERROR_INTERNAL_ERROR

[4878] 16.3. Use Cases

Driver Initialization

[4879] The VxD containing DM_VXFAC is loaded, either at boot time(static VxD) or on a call to CreateFile( ) (dynamic VxD).

[4880] DM_VXFAC receives an EV_VXD_INIT message on its drv terminal.

[4881] DM_VXFAC checks if an instance of the device has already beencreated, if so DM_VXFAC returns CMST_FAILED.

[4882] DM_VXFAC creates an instance of the device.

[4883] DM_VXFAC parameterizes the device instance with the registry pathfor the device settings (reg_root property).

[4884] DM_VXFAC activates the device instance and returns CMST_OK.

Driver Cleanup

[4885] The VxD containing DM_VXFAC is unloaded, either at systemshutdown (static VxD) or on a call to CloseHandle( ) (dynamic VxD).

[4886] DM_VXFAC receives an EV_VXD_CLEANUP message on its drv terminal.

[4887] DM_VXFAC checks if the device instance has already beendestroyed, if so DM_VXFAC returns CMST_OK.

[4888] DM_VXFAC deactivates and destroys the device instance.

[4889] DM_VXFAC returns CMST_OK.

Synchronous Operations

[4890] DM_VXFAC receives an EV_VXD_MESSAGE event on its drv terminal andtranslates it into an I_DIO operation.

[4891] DM_VXFAC invokes the proper operation on dio (open, close,cleanup, read, write or ioctl).

[4892] The call returns a completion status and DM_VXFAC translates itto a Win32 status. If operation is read, write or ioctl DM_VXFAC copiesthe translated status into the cplt_s field of the I/O control datablock and updates the number of bytes copied to the output buffer.

[4893] DM_VXFAC completes the operation.

Asynchronous Open Close Operations

[4894] DM_VXFAC receives an EV_VXD_MESSAGE event (for DIOC_OPEN orDIOC_CLOSEHANDLE) on its drv terminal and translates it into an I1DIOoperation.

[4895] DM_VXFAC invokes the proper operation on dio (open, close orcleanup).

[4896] The invoked operation returns CMST_PENDING to indicateasynchronous completion.

[4897] DM_VXFAC waits on a semaphore until the operation has completed.At a later time, the dio.complete operation is invoked on DM_VXFAC toindicate the pending operation has completed. DM_VXFAC then signals thesemaphore.

[4898] DM_VXFAC wakes up from waiting on the semaphore and completes thelife-cycle operation.

Asynchronous I/O Operations

[4899] DM_VXFAC receives an EV_VXD_MESSAGE event (read, write or otherI/O controls) on its drv terminal and translates it into an I_DIOoperation.

[4900] DM_VXFAC invokes the proper operation on dio (read, write orioctl).

[4901] The invoked operation returns CMST_PENDING to indicateasynchronous completion.

[4902] DM_VXFAC returns −1 to the operating system to indicate theoperation is pending (Overlapped I/O).

[4903] At a later time, the dio.complete operation is invoked onDM_VXFAC to indicate the pending operation has completed.

[4904] DM_VXFAC translates the completion status as specified by thestatus_xlat property and updates the completion status in the I/Ocontrol data block.

[4905] DM_VXFAC passes the number of bytes copied to the output bufferin the DIOCParams structure received with the I/O control.

[4906] DM_VXFAC completes the pending operation by invokingVWIN32_DIOCCompletionRoutine( ).

[4907] 17. Notes

[4908] DM_VXFAC expects that all recognized events received through thedrv terminal are received while the interrupts are enabled. For allunrecognized events, DM_VXFAC does not assume that the interrupts willbe enabled; it returns immediately without any operation.

[4909] DM_VXFAC allows only one file to be open at any time. DM_VXFACfails additional open requests. DM_VXFAC may be updated in the future tohandle mutliple nested open requests.

[4910] For all I/O control requests, DM_VXFAC maps user mode buffersinto kernel mode address space before forwarding I_DIO operationsthrough the dio terminal. For all IOCTL requests other then read andwrite, DM_VXFAC always maps the output buffer passed to DeviceloControl(). The buffer mapping is done by using the LinPageLock( ) andLinPageUnlock( ) kernel mode API.

[4911] DM_VXFAC uses buffered I/O for all operations, but DM_VXFACalways maps the user's buffers into the kernel mode address space. Thisbuffer mapping forces all operations to use direct I/O, even though it'sbuffered I/O from the operating system standpoint.

[4912] The B_DIO bus DM_VXFAC passes to each I_DIO operation isallocated on the stack of the current execution context. If an operationis to be completed asynchronously, DM_VXFAC expects that the B_DIO buswill be duplicated and passed back to dio.complete when the operationhas completed.

[4913] The B_DIO.irpp field is used internally by DM_VXFAC. DM_VXFACexpects that this field is not modified by the device instance and ispassed back to dio.complete for the completion of asynchronousoperations.

[4914] DM_VXFAC never fails DIOC_OPEN messages even if the I_DIO.openoperation generated by DM_VXFAC fails. This is due to the behavior ofthe Windows 95/98 operating system. However, DM_VXFAC keeps an “open”state on the device instance. If an open attempt does fail, DM_VXFACfails all I/O controls sent to the device until it is either openedsuccessfully or closed. DM_VXFAC passes additional open attempts untilsuccess.

[4915] For asynchronous, overlapped I/O operations, it is not advised tocomplete these operations while the interrupts are disabled. This isbecause DM_VXFAC during dio.compete needs to free the operationcompletion context by calling cm_bus_free( ). In doing so, theinterrupts become enabled which could cause unpredictable results.

Enumerators DM_REN—Device Enumerator on Registry

[4916]FIG. 143 illustrates the boundary of the inventive DM_REN part.

[4917] DM_REN is a registry-based device enumerator specificallydesigned to work in Windows NT kernel-mode. DM_REN is parameterized withthe driver root registry key (as a string).

[4918] Upon activation of DM_REN, the edev terminal provides enumerationof devices as defined in ParamDevices subkey of the root registry key;the eprp terminal provides enumeration of the persistent properties foreach device obtained through edev.

[4919] The properties manipulated through the eprp terminal cannot bemodified (set operation will fail).

[4920] Full registry path to the specified device key can be obtainedfrom DM_REN by reading a property on its boundary. The enumeration IDreceived from the device is used for identifying the particular deviceinstance.

[4921] DM_REN supports multiple simultaneous queries for devices andproperties on a device.

[4922] DM_REN does not modify or delete any information from theregistry.

[4923] This part is available only in Windows NT/95/98 Kernel Modeenvironments.

[4924] 1. Boundary

[4925] 1.1. Terminals

[4926] Terminal “edev” with direction “In” and contract I_DEN. Note:DM_REN receives queries for enumerating the installed devices.

[4927] Terminal “eprp” with direction “In” and contract I_A_PROP. Note:DM_REN receives queries for obtaining the specific propertiesinformation for an installed device.

[4928] 1.2. Events and Notifications

[4929] None.

[4930] 1.3. Special Events, Frames, Commands or Verbs

[4931] None

[4932] 1.4. Properties

[4933] Property “reg_root” of type “UNICODEZ”. Note: Specifies a rootRegistry key name. The device instance keys are stored into itsParameters\Devices sub-key. This property is mandatory.

[4934] Property “dev_name_base” of type “UNICODEZ”. Note: This propertyis used as the base for making device names. The name is created as:

[4935] \Device\<device_name_base><dev subkey>

[4936] 2. Encapsulated Interactions

[4937] DM_REN relies on following services from the Windows NT kernelmode support routines:

[4938] ZwOpenKey—open an existing key in the registry

[4939] ZwEnumerateKey—to enumerate all existing sub-keys

[4940] ZwQueryValueKey—to obtain the current value of the specifiedvalue entry

[4941] ZwEnumerateValueKey—to enumerate all value entries of the openedregistry key

[4942] ZwClose—close previously opened registry key

[4943] InitializeObjectAttributes—used to initialize the objectattributes needed for the subsequent call to ZwOpenKey

[4944] 3. Specification

[4945] 4. Responsibilities

[4946] 1. Implement the I_DEN interface by enumerating theParameters\Devices sub-key of the driver's Registry key, specified bythe reg_root property.

[4947] 2. Provide the following data for each device instance:

[4948] class name for the device instance

[4949] registry path to device's settings

[4950] Win32 name(s) to associate with the device

[4951] device name (in kernel-mode name space)

[4952] 3. Implement I_A_PROP interface. Supports all propertyenumeration functionality and property get calls. Does not supportchanging of the property values. Only one property issupported-reg_root.

[4953] 5. Theory of Operation

[4954] 5.1. State Machine

[4955] None.

[4956] 5.2. Main Data Structures

[4957] None.

[4958] 5.3. Mechanisms

Creating a Unique Identifier for the Device Instances

[4959] When DM_REN enumerates all device registry keys under driverregistry key, it gives them a unique identifier. The identifier is usedfor obtaining the properties for the selected device (after theenumeration). DM_REN identifies the devices by creating a unique IDusing the enumeration index. The sequence of creating this unique IDfollows:

[4960] 1. Get the least significant 16-bits from the enumeration index

[4961] 2. Make 8-bits check sum (XOR) of all characters in the Registrykey name.

[4962] 3. Combine into one DWORD the least significant byte of theRegistry name length, the calculated check sum and the least significantword (16-bits) from the device enumeration index. This DWORD will be thedevice identifier.

Create a Query Handler

[4963] DM_REN uses ClassMagic™ handles with an owner key to keep trackof all open queries. DM_REN allocates a memory buffer to keep some queryinformation and store the pointer to this buffer into the handlercontext. When DM_REN is destroyed, it enumerates the handles with itsown key and releases all allocated resources.

DM_PEN—PCI Device Enumerator

[4964]FIG. 144 illustrates the boundary of the inventive DM_PEN part.

[4965] DM_PEN a DriverMagic™ part, which is specifically designed towork in Windows NT kernel-mode. It enumerates PCI devices using specificcriteria.

[4966] Before its activation, DM_PEN receives the name of the driverroot registry key—reg_root, pointer to the driver object associated withthis device—drv_objp and device and vendors IDs and masks. Using thespecified information, it locates all devices of a specified class on aPCI bus. DM_PEN collects information about the resources of the devices,initializes them if necessary and gives a unique name to each of them.Some of the resources are obtained by reading the information storedinto Parameters\Devices sub-key of the reg_root key. If those keys arenot set in the Registry, the device will use their default values.DM_PEN can work properly even without having this information set in theRegistry.

[4967] When DM_PEN receives an enumeration query through edev terminal,it returns an id, which is used as an identifier for the particulardevice instance. This id shall be used for property enumeration the eprpterminal. The identifier is valid only through the DM_PEN lifecycle.

[4968] DM_PEN supports property enumeration calls through its eprpterminal. It does not support the property “set” operation from theI_A_PROP interface. DM_PEN supports multiple properties with the samename. For those properties, a two digit decimal number is added at theend of the name.

[4969] DM_PEN supports multiple simultaneously open enumeration queriesfor both types-device and property queries.

[4970] NOTE: The initialization and activation of this component must berunning at IRQL PASSIVE_LEVEL.

[4971] 6. Boundary

[4972] 6.1. Terminals

[4973] Terminal “edev” with direction “in” and contract In: I_DEN. Note:DM_PEN receives queries for enumerating the installed devices.

[4974] Terminal “eprp” with direction “in” and contract In: I_A_PROP.Note: DM_PEN receives queries for obtaining the specific propertiesinformation for an installed device.

[4975] 6.2. Events and Notifications

[4976] DM_PEN has no incoming and outgoing events and notifications.

[4977] 6.3. Special Events, Frames, Commands or Verbs

[4978] None

[4979] 6.4. Properties

[4980] Property “reg_root” of type “unicodez”. Note: Specifies the rootRegistry key name for the driver. The device instance keys are storedinto its Parameters\Devices sub-key. This property is mandatory.

[4981] Property “drv_objp” of type “uint32”. Note: pointer to the driverobject.

[4982] Property “dev_name_base” of type “unicodez”. Note: This propertyis used as the base for making device names. The name is created as:

[4983] \Device\<device_name_base>n Where n is the sequential number ofthe device during the device enumeration This property is mandatory.

[4984] Property “vendor_id” of type “uint32”. Note: Vendor ID. Thisproperty is mandatory.

[4985] Property “vendor id mask” of type “uint32”. Note: Vendor ID mask.The default is 0×FFFFFFFF

[4986] Property “device_id” of type “uint32”. Note: Device ID. Thisproperty is mandatory.

[4987] Property “device_id mask” of type “uint32”. Note: Device ID mask.The default is 0×FFFFFFFF

[4988] Property “subsys_vendor_id” of type “uint32”. Note: SubsystemVendor ID. This property is mandatory.

[4989] Property “subsys_vendor_id_mask” of type “uint32”. Note:Subsystem Vendor ID mask. The default is 0×FFFFFFFF

[4990] Property “subsys_device_id” of type “uint32”. Note: Subsystemdevice ID. This property is mandatory.

[4991] Property “subsys_device_id mask” of type “uint32”. Note:Subsystem device ID mask. The default is 0×FFFFFFFF

[4992] 6.5. Properties Exported Through eprp Terminal

[4993] Property “bus” of type “uint32”. Note: device bus number

[4994] Property “slot” of type “uint32”. Note: device slot number

[4995] 7. Encapsulated Interactions

[4996] DM_PEN relies on following services from the Windows NT kernelmode support routines:

[4997] HalGetBusData—obtains details about a given slot or address on aparticular I/O bus. By changing this function's parameters, it ispossible to scan all devices.

[4998] HalAssignSlotResources—determines the resource requirements ofthe target device, allocates them, initializes the target device withits assigned resources, and returns the assignments to the caller.

[4999] IoAssignResources—erase the claim on resources (made byHalAssignSlotResources) in the registry when the driver is unloaded.

[5000] HalTranslateBusAddress—translates a bus-specific address into thecorresponding system logical address.

[5001] 8. Packaging and Environment Dependencies

[5002] DM_PEN is a DriverMagic™ part for use in a Windows NT kernel-modedriver.

[5003] 9. Specification

[5004] 10. Responsibilities

[5005] 1. Implement the I_DEN interface by searching for PCI devicesusing various criteria, such as Vendor ID, Device ID, etc.

[5006] 2. Obtain device specific information from the Parameters\Devicessub-key of the driver's Registry key, specified by the reg_rootproperty.

[5007] 3. Provide the following data for each device instance:

[5008] class name for the device instance

[5009] Win32 name(s) to associate with the device

[5010] device name (in kernel-mode name space)

[5011] 4. Allocate resources for every device

[5012] 5. Implement I_A_PROP interface. Supports all propertyenumeration functionality and property get calls. Support multipleproperties with the same name. Does not support changing of the propertyvalues.

[5013] 11. Theory of Operation

[5014] 11.1. State Machine

[5015] DM_PEN has no state machine

[5016] 11.2. Main Data Structures

[5017] Device Table-table consists of all resource information for eachenumerated device.

[5018] 11.3. Mechanisms

Creating a Unique Identifier for the Device Instances

[5019] When DM_PEN enumerates all device registry keys under driverregistry key, it gives them a unique identifier. The identifier is usedfor obtaining the properties for the selected device (after theenumeration). DM_PEN uses DriverMagic™ handles with an owner key toidentify the specific device instance.

Creating a Query Handle

[5020] DM_PEN uses DriverMagic™ handles with an owner key to keep trackof all open queries. DM_PEN allocates a memory buffer to keep some queryinformation and store the pointer to this buffer into the handlecontext. When DM_PEN is destroyed, it enumerates the handles with itsown key and releases all allocated resources.

Creating a Device Name

[5021] The device name has the follow structure:

[5022] \Device\dev_name_basen

[5023] Where dev_name_base is a property supplied by the caller and n isa sequential number of discovering the device.

[5024] Note: n starts from 1.

Creating a Device Instance reg_root Path

[5025] The device reg_root path is created by adding to the driverreg_root path \Parameters\Devices\nnnn. Where nnnn is a four digitdecimal number with leading zeros. It has the same meaning as n indevice name creation. E.g. the device reg_root has the following format:

[5026] <driver reg_root>\Parameters\Devices\nnnn

Creating a Class Name for the Device

[5027] The device class name is obtained from DevPartClass Registry keyunder device reg_root tree. If this key is not set (from the installer),the class name will be an empty string.

Creating a Device Friendly Name

[5028] The device class name is obtained from FriendlyName Registry keyunder device reg_root tree. If this key is not set (from the installer)the device name is used instead.

[5029] 12. Unresolved Issues

[5030] If multiple PCI devices are installed in the system, there is noreliable way to keep persistent data associated with each device. If thedevices are moved to different slots on the PCI bus, a reconfigurationof the devices' parameters will be necessary. Note that this is aproblem with Plug-and-Play devices in general, not a problem with thePCI enumerator.

DM_PCEN—PCMCIA Device Enumerator

[5031]FIG. 145 illustrates the boundary of the inventive DM_PCEN part.

[5032] DM_PCEN a DriverMagic™ part that is specifically designed to workin Windows NT kernel-mode. It enumerates PCMCIA devices using specificcriteria.

[5033] Before its activation, DM_PCEN receives as properties the name ofthe device manufacturer and the device model name. Using thisinformation, it locates all matching PCMCIA devices installed in thesystem. DM_PCEN collects information about the resources of the devicesand gives a unique name to each of them. Some of the resources areobtained by reading the information stored into Parameters\Devicessub-key of the reg_root key. If those keys are not set in the Registry,the device will use their default values. DM_PCEN can work properly evenwithout having this information set in the Registry.

[5034] When DM_PCEN receives an enumeration query through edev terminal,it returns an ID, which is used as an identifier for the particulardevice instance. This ID is used for property enumeration through theeprp terminal. The identifier is valid only through the DM_PCEN instancelifetime. DM_PCEN supports property enumeration calls through its eprpterminal. It does not support the property set operation from theI_A_PROP interface. DM_PCEN supports multiple properties with the samename. For those properties, a two digit decimal number is added at theend of the name.

[5035] DM_PCEN supports multiple simultaneously open enumeration queriesfor both types-device and property queries.

[5036] Since the PCMCIA support in Windows NT 4.0 does not allow morethan one PCMCIA card with the same manufacturer/device name pair, theenumerator can find either zero or one PCMCIA devices.

[5037] 13. Boundary

[5038] 13.1. Terminals

[5039]

[5040] Terminal “edev” with direction “in” and contract In: I_DEN. Note:DM_PCEN receives queries for enumerating the installed devices.

[5041] Terminal “eprp” with direction “in” and contract In: I_A_PROP.Note: DM_PCEN receives queries for obtaining the specific propertiesinformation for an installed device.

[5042] 13.2. Events and Notifications

[5043] DM_PCEN has no incoming and outgoing events and notifications.

[5044] 13.3. Special Events, Frames, Commands or Verbs

[5045] None

[5046] 13.4. Properties

[5047] Property “reg_root” of type “unicodez”. Note: Specifies the rootRegistry key name for the driver. The device instance keys are storedinto its Parameters\Devices sub-key. This property is mandatory.

[5048] Property “manufacturer” of type “unicodez”. Note: Devicemanufacturer name. This property is mandatory.

[5049] Property “device” of type “unicodez”. Note: Device model name.This property is mandatory.

[5050] 13.5. Properties Exported Through the eprp Terminal

[5051] Property “bus” of type “uint32”. Note: device bus number

[5052] Property “slot” of type “uint32”. Note: device slot number

[5053] Property “manufacturer” of type “unicodez”. Note: devicemanufacturer name

[5054] Property “device” of type “unicodez”. Note: device model name

[5055] Property “reg_root” of type “unicodez”. Note: registry path tothe specified device instance key (per device instance)

[5056] Property “class_name” of type “asciiz”. Note: class_name of partto be created to handle this device instance (may be empty)

[5057] Property “device_name” of type “unicodez”. Note: name to use forregistering the device

[5058] Property “friendly_name” of type “unicodez”. Note: Win32 alias(does not include the \??\prefix)

[5059] Property “port_base” of type “BINARY (uint64)”. Note: I/O portbase. (8-byte physical address). Could be more than 1 per device.

[5060] Property “port_length” of type “uint32”. Note: Specifies therange of the I/O port base. Could be more than 1 per device.

[5061] Property “mem_base” of type “BINARY (uint64)”. Note: The physicaland bus-relative memory base (8-byte physical address). Could be morethan 1 per device.

[5062] Property “mem_length” of type “uint32”. Note: Specifies the rangeof the memory base. Could be more than 1 per device.

[5063] Property “irq_level” of type “uint32”. Note: Bus-relative IRQL.Could be more than 1 per device.

[5064] Property “irq_vector” of type “uint32”. Note: Bus-relativevector. Could be more than 1 per device.

[5065] Property “irq_affinity” of type “uint32”. Note: Bus-relativeaffinity. Could be more than 1 per device.

[5066] Property “dma_channel” of type “uint32”. Note: DMA channelnumber. Could be more than 1 per device.

[5067] Property “dma_port” of type “uint32”. Note: MCA-type DMA port.Could be more than 1 per device.

[5068] 14. Encapsulated Interactions

[5069] DM_PCEN relies on following services from the Windows NT kernelmode support routines:

[5070] ZwOpenKey—open an existing key in the registry

[5071] ZwEnumerateKey—to enumerate all existing sub-keys

[5072] ZwQueryValueKey—to obtain the current value of the specifiedvalue entry

[5073] ZwEnumerateValueKey—to enumerate all value entries of the openedregistry key

[5074] ZwClose—close previously opened registry key

[5075] InitializeObjectAttributes—used to initialize the objectattributes needed for the subsequent call to ZwOpenKey

[5076] HalTranslateBusAddress—translates a bus-specific address into thecorresponding system logical address.

[5077] 15. Packaging and Environment Dependencies

[5078] DM_PCEN is a DriverMagic™ part for use in a Windows NTkernel-mode driver.

[5079] 16. Specification

[5080] 17. Responsibilities

[5081] 1. Implement the I_DEN interface by searching for PCMCIA devicesusing the manufacturer/device criteria.

[5082] 2. Obtain device specific information from the Parameters\Devicessub-key of the driver's Registry key, specified by the reg_rootproperty.

[5083] 3. Provide the following data for each device instance:

[5084] class name for the device instance

[5085] Win32 name(s) to associate with the device

[5086] device name (in kernel-mode name space)

[5087] 4. Obtain device resources from

[5088] ‘\Registry\Machine\Hardware\Description\System\PCMCIA PCCARDs’registry key

[5089] 5. Implement I_A_PROP interface. Supports all propertyenumeration functionality and property get calls. Support multipleproperties with the same name. Does not support changing of the propertyvalues.

[5090] 18. Theory of Operation

[5091] 18.1. State Machine

[5092] DM_PCEN has no state machine

[5093] 18.2. Main Data Structures

[5094] Device Table—a table that consists of all resource informationfor each enumerated device.

[5095] 18.3. Mechanisms

Obtaining Device Resurces

[5096] DM_PCEN search the Registry key

[5097] ‘\Registry\MachineHardware\Description\System\PCMCIA PCCARDs’ forthe value with matched the device name (see Creating a device namebelow). This registry value contains REG_FULL_RESOURCE_DESCRIPTOR, whichcontains all allocated for the specific device resource.

Creating a Unique Identifier for the Device Instances

[5098] When DM_PCEN enumerates all device registry keys under driverregistry key, it gives them a unique identifier. The identifier is usedfor obtaining the properties for the selected device (after theenumeration). DM_PCEN uses DriverMagic™ handles with an owner key toidentify the specific device instance.

Creating a Query Handle

[5099] DM_PCEN uses DriverMagic™ handles with an owner key to keep trackof all open queries. DM_PCEN allocates a memory buffer to keep somequery information and store the pointer to this buffer into the handlecontext. When DM_PCEN is destroyed, it enumerates the handles with itsown key and releases all allocated resources.

Creating a Device Name

[5100] As device name is used the value of the Registry value

[5101] ‘\Registry\Machine\CurrentControlSet\Services\PCMCIA\DataBase<manufacturer>\<device >\Driver’

Creating a Device Instance reg_root Path

[5102] The device reg_root path is created by adding to the driverreg_root path \Parameters\Devices\nnnn. Where nnnn is a four digitdecimal number with leading zeros. It has the same meaning as n indevice name creation. The device reg_root has the following format:

[5103] <driver reg_root>\Parameters\Devices\nnnn

Creating a Class_Name for the Device

[5104] The device class name is obtained from DevPartClass registry keyunder device reg_root tree. If this key is not set (by the installer),the class name will be an empty string.

Creating a Device Friendly Name

[5105] The device class name is obtained from FriendlyName registry keyunder device reg_root tree. If this key is not set (by the installer)the device name is used instead.

[5106] 19. Unresolved Issues

[5107] 1. If multiple PCMCIA devices are installed in the system, thereis no reliable way to keep persistent data associated with each device.If the devices are moved to different socket on the PCMCIA adapter, areconfiguration of the devices' parameters will be necessary.

[5108] The above note is largely irrelevant since the PCMCIA support inWindows NT 4.0 does not provide for multiple instances of the samePCMCIA device in the system.

Registrars DM_SGR—Singleton Registrar

[5109]FIG. 146 illustrates the boundary of the inventive DM_SGR part.

[5110] DM_SGR is used to register its host assembly under a given nameand to make it available for binding. Assemblies of this type are knownas singletons.

[5111] On activation, DM_SGR registers its host assembly under a givenname (parameterized through the name property). The instance name mayonly be registered once. If the host assembly is instantiated more thenonce, DM_SGR activation fails.

[5112] DM_SGR can be disabled by simply removing the part from its hostassembly or for convenience, by setting the name property to “”.

[5113] DM_SGR has no terminals and does not contain any functionalityexcept on activation.

[5114] 1. Boundary

[5115] 1.1. Terminals

[5116] None.

[5117] 1.2. Events and Notifications

[5118] None.

[5119] 1.3. Special Events, Frames, Commands or Verbs

[5120] None.

[5121] 1.4. Properties

[5122] Property “name” of type “ASCIZ”. Note: Specifies the instancename that DM_SGR's host assembly should be registered under. Instancename must be less then 128 characters. If name is ““DM_SGR is disabledand does nothing. Default value is ””.

[5123] 2. Encapsulated Interactions

[5124] None.

[5125] 3. Specification

[5126] 4. Responsibilities

[5127] 27. Register the host assembly by the specified name (nameproperty) to make it available for binding.

[5128] 28. Prevent its host assembly from being instantiated more thenonce.

[5129] 5. Theory of Operation

[5130] 5.1. State Machine

[5131] None.

[5132] 5.2. Main Data Structures

[5133] None.

[5134] 5.3. Mechanisms

Preventing Host Assembly from Multiple Instantiations

[5135] On activation, if the name property is “”, DM_SGR does nothingand returns CMST_OK. In this case, the host assembly may be instantiatedmore then once. Otherwise, DM_SGR registers the instance name with theobject ID of its containing assembly.

[5136] When the assembly is instantiated for the first time, theinstance name registration and DM_SGR's activation succeeds. If the sameassembly is instantiated more then once, DM_SGR's activation fails withCMST_DUPLICATE (instance names may only be registered once).

[5137] DM_SGR deregisters the instance name on deactivation.

[5138] 5.4. Use Cases

Implementing a Singleton Assembly

[5139] 1. The singleton assemblies part table contains the DM_SGR partalong with any other parts the assembly uses.

[5140] 2. The DM_SGR part is parameterized with an instance name for theassembly (e.g., hard parameterization).

[5141] 3. The assembly is created and activated (there are noconnections to DM_SGR).

[5142] 4. DM_SGR registers the instance name with the object ID of theassembly and its activation succeeds.

[5143] 5. Any additional attempts to create and activate the singletonassembly a second time will fail with CMST_DUPLICATE.

[5144] The assembly is deactivated and destroyed. DM_SGR deregisters theinstance name on deactivation.

DM_DSTK—Device Stacker

[5145]FIG. 147 illustrates the boundary of the inventive DM_DSTK part.DM_DSTK can be used in a WDM/NT driver to attach devices created by theDriverMagic NT or WDM device factory (DM_FAC) to lower level devicedrivers.

[5146] DM_DSTK should be inserted in the I_A_FACT connection fromDM_FAC-it uses the I_A_FACT.activate/deactivate operations to performits operations.

[5147] DM_DSTK is a pure filter-it has no state of its own and relies onthe property storage provided by the parts connected to prp to keepcontext between calls. The device instances used with DM_DSTK must bebuilt to cooperate with it-see the notes in the Terminals section below.

[5148] 6. Boundary

[5149] 6.1. Terminals

[5150] Terminal “i_fac” with direction “In” and contract I_A_FACT. Note:Operations on this terminal are passed transparently to o_fac, exceptsactivate and deactivate—DM_DSTK performs attaching/detaching to thelower-level device before activate and after deactivate is passed too_fac. If attaching to the device fails, activate is not passed to o_facand DM_DSTK return an error status.

[5151] Terminal “o_fac” with direction “Out” and contract I_A_FACT.Note: Operations from i_fac are passed to this output. See i_fac above.

[5152] Terminal “prp” with direction “Out” and contract I_A_PROP. Note:This output must be connected so that DM_DSTK can access the propertiesof the same parts that are created through the o_fac terminal. Normally,both these outputs are connected (directly or indirectly) to the controlterminals of a DriverMagic part array (DM_ARR). For DM_DSTK to operate,the parts created through o_fac must provide storage for properties thatis accessible to DM_DSTK through its prp terminal. See the notes belowthis table.

[5153] The parts created through o_fac should provide storage for thefollowing properties. All of these properties must be available,otherwise DM_DSTK will not activate the instance.

[5154] dev_objp (UINT32)-keeps the device object pointer of the WDMdevice associated with the instance. This value is expected to be set(normally by DM_FAC) before i_fac.activate is called.

[5155] low_dev_name (unicode)-keeps the name of the device to whick thisinstance is to be attached. This property is read by DM_DSTK and must beset to a correct value before i_fac.activate is called. Typically, thisproperty is set on the device instance through the Registry (seeDM_PRM).

[5156] low_dev_filep (UINT32)-DM_DSTK sets this property to the fileobject associated with the opened lower-level device (specified bylow_dev_name). This value is valid in the scope of the part(s) createdthrough o_fac while they are active. This value should be treated bythese parts as read-only and never modified.

[5157] low_dev_objp (UINT32)-DM_DSTK sets this property to the deviceobject of the device specified by low_dev_name. This value is valid inthe scope of the part(s) created through o_fac while they are active.

[5158] 6.2. Events and Notifications

[5159] None.

[5160] 6.3. Special Events, Frames, Commands or Verbs

[5161] None.

[5162] 6.4. Properties

[5163] None.

[5164] 7. Encapsulated Interactions

[5165] DM_DSTK uses the following WDM services:

[5166] IoGetDeviceObjectPointer-open a device

[5167] ObDereferenceObject-close a device

[5168] IoAttachDeviceToDeviceStack, IoDetachDevice-attach/detach to andfrom lower-level device.

[5169] 8. Specification

[5170] 9. Responsibilities

[5171] Pass all i_fac operations to o_fac.

[5172] On i_fac.activate, before it is passed to o_fac: open and attachto device specified by low_dev_name, store file and device objectpointer in low_dev_filep and low_dev_objp properties.

[5173] On i_fac.deactivate, after it is passed to o_fac: reverse theactions taken on i_fac.activate (detach and close lower device).

[5174] 10. Theory of Operation

[5175] 10.1. State Machine

[5176] None.

[5177] 10.2. Mechanisms

[5178] None.

Factory Interface Adaptors DM_CBFAC—Create/Bind Factory

[5179]FIG. 148 illustrates the boundary of the inventive DM_CBFAC part.

[5180] DM_CBFAC is a part factory that creates and binds to parts byname. DM_CBFAC can be used to manage singletons (parts that may only beinstantiated once) or can be used to register and bind to specific partinstances.

[5181] DM CBFAC supports the standard factory operations—create,destroy, activate and deactivate. The query operations get_first andget_next are passed out through o_fac without modification.

[5182] The life cycle of the parts created through DM_CBFAC is handledthrough reference counting. Each instance created using DM_CBFAC isexpected to expose reference count properties used specifically byDM_CBFAC. These properties are incremented and decremented through-outthe life cycle of the instance (creation, destruction, activation anddeactivation). An instance is only deactivated or destroyed when thecorresponding reference count reaches zero. This technique is similar tothe way COM objects handle the life cycle of interface pointers.

[5183] DM_CBFAC has no state. The instance name, reference counts andany other information maintained by the factory are kept on the instancecreated by DM_CBFAC as properties. The actual names of these propertiesare controlled through properties exposed by DM_CBFAC.

[5184] The actual factory and instance parameterization operations arehandled by a separate part connected to the o_fac and o_prp terminals.DM_CBFAC expects that the part connected to these terminals handles allof this functionality. Typically, the part array (DM_ARR) is connectedto these terminals.

[5185] 1. Boundary

[5186] 1.1. Terminals

[5187] Terminal “i_fac” with direction “In” and contract I_A_FACT. Note:v-table, synchronous, infinite cardinality This terminal is used tocreate, destroy, activate and deactivate part instances. Depending onhow DM_CBFAC is used, parts created through DM_CBFAC may only beinstantiated one time. Subsequent creations result in DM_CBFAC bindingto an existing instance. All operations are subject to referencecounting—DM_CBFAC keeps track of the number of times an instance wascreated and activated. An instance is deactivated or destroyed only whenits reference count reaches zero (cumulative). The query operationsgetfirst and getnext are passed directly through the o_fac terminalwithout modification.

[5188] Terminal “o_fac” with direction “Out” and contract I_A_FACT.Note: v-table, synchronous, cardinality 1 This terminal is used byDM_CBFAC to create, destroy, bind, activate and deactivate parts onbehalf of the requests received from the i_fac terminal. The queryoperations i_fac.getfirst and i_fac.get_next are passed directly throughthis terminal without modification.

[5189] Terminal “o_prp” with direction “Out” and contract I_A_PROP.Note: v-table, synchronous, cardinality 1 DM_CBFAC uses this terminal toeither set properties on newly created instances or to bind to existinginstances. See the Properties section for more information.

[5190] 1.2. Events and Notifications

[5191] None.

[5192] 1.3. Special Events, Frames, Commands or Verbs

[5193] None.

[5194] 1.4. Properties

[5195] Property “dflt_class_name” of type “ASCIIZ”. Note: Specifies theclass name of the part that DM_CBFAC creates on i_fac.create operations(overrides the name specified in the B_A_FACT bus). This property isused only if the force_dflt_class property is TRUE. Default is “”.

[5196] Property “force_dflt_class” of type “BOOL”. Note: If TRUE,DM_CBFAC uses the dflt_class_name property as the class to create oni_fac.create. DM_CBFAC uses the name specified in the B_A_FACT bus asthe instance name (set on the newly created part as the name_propproperty). In this case the name in the B_A_FACT bus cannot be NULL. IfFALSE, the name specified in the B_A_FACT bus is used as both the classname and the instance name (creation of singletons). Default is FALSE.

[5197] Property “reg_root” of type “ASCIIZ”. Note: Registry root pathprefix for instances created by DM_CBFAC. On instance creation, DM_CBFACconcatenates this property value with the instance name and sets it asthe value of the (reg_prop) property on the newly created instance.Default is “”.

[5198] Property “name_prop” of type “ASCIIZ”. Note: Name of the instancename property on part instances created by DM_CBFAC. Upon instancecreation, DM_CBFAC sets this property to the appropriate instance name.The calculation of the instance name is described in the Mechanismssection below. This property is used by DM_CBFAC to bind to existinginstances. Default is “name”.

[5199] Property “reg_prop” of type “ASCIIZ”. Note: Name of the registrypath property on part instances created by DM_CBFAC. Upon instancecreation, DM_CBFAC sets this property to the appropriate registry path(concatenates the reg_root property value with the instance name).Default is “reg_root”.

[5200] Property “c_refcnt_prop” of type “ASCIIZ”. Note: Name of thecreation reference count property on part instances created by DM_CBFAC.This property value is incremented and decremented as a particularinstance is created and destroyed. The instance is only actuallydestroyed when this count reaches zero. Default is “c_refcnt”.

[5201] Property “a_refcnt_prop” of type “ASCIIZ”. Note: Name of theactivation reference count property on part instances created byDM_CBFAC. This property value is incremented and decremented as aparticular instance is activated and deactivated. The instance is onlyactually deactivated when this count reaches zero. Default is“a_refcnt”.

[5202] 1.5. Instance Properties

[5203] The instances created by DM_CBFAC are expected to support aspecific set of properties used by the factory. All of the followingproperties must not be modified by the part instance except onconstruction and destruction. The factory initializes these propertiesafter instance creation. These properties are described in the tablebelow:

[5204] Property “(name_prop)” of type “ASCIIZ”. Note: This contains thename of the part instance. This is used by DM_CBFAC to identify aninstance of a particular part. This allows the factory to bind to aninstance by name. The instance name is either dflt_class_name or it'sthe name specified in the B_A_FACT bus on i_fac.create. This depends onhow the factory is used. See the Mechanisms section below for moreinformation. This property is set after the instance is created.

[5205] Property “(c_refcnt_prop)” of type “UINT32”. Note: Active-time.Creation/destruction reference count. Every time a part is created or isbound to by name, the factory increments this property value. By thesame token each time a part is destroyed it is decremented. An instanceis only destroyed when the reference count reaches zero. This propertyis used during instance creation and destruction.

[5206] Property “(a_refcnt prop)” of type “UINT32”. Note: Active-time.Activation/deactivation reference count. Every time a part isactivated/deactivated the factory increments/decrements this propertyvalue respectively. An instance is only deactivated when the referencecount reaches zero. This property is used during instance activation anddeactivation.

[5207] Additionally the instances may support any of the followingproperties. DM_CBFAC tries to set these properties on the instance aftercreation, if the property does not exist it is ignored.

[5208] Property “(reg_prop)” of type “ASCIIZ”. Note: Optional. Registrypath for settings, parameters, etc. The use of this property is definedby the instance created by the factory. The value of this property isthe instance name prefixed by the value of the DM_CBFAC reg_rootproperty. This path usually defines the location where device specificsettings and parameters are stored.

[5209] 2. Encapsulated Interactions

[5210] None.

[5211] 3. Specification

[5212] 4. Responsibilities

[5213] 1. Create or bind to part instances by name.

[5214] 2. Upon successful first-time part creation, set the name_propand reg_prop properties on the newly created instance to the appropriatevalues.

[5215] 3. As instances are created, destroyed, activated and deactivatedupdate the instance reference count properties. Only destroy ordeactivate an instance when the appropriate reference count reacheszero.

[5216] 4. Pass the query operations of the i_fac terminal through theo_fac terminal without modification.

[5217] 5. Theory of Operation

[5218] 5.1. Mechanisms

Calculation of Class and Instance Names

[5219] The way the class and instance names are calculated depends onhow the factory is being used. This virtually depends on whether theclass name property is being enforced (force_dflt_class is TRUE) andwhat name is passed on the i_fac.create operation (B_A_FACT.namep).

[5220] Below summarizes how these names are calculated based uponfactory usage:

[5221] 1. force_dflt_class is TRUE:

[5222] a. if B_A_FACT.namep !=NULL then the class name is the value ofthe dflt_class_name property and the instance name is the name specifiedin the bus.

[5223] b. if B_A_FACT.namep==NULL then both the class and instance nameis the value of the dflt_class_name property.

[5224] 2. force_dflt_class is FALSE:

[5225] a. if B_A_FACT.namep !=NULL then both the class and instance nameis the name specified in the bus.

[5226] b. if B_A_FACT.namep==NULL then this is illegal and the factoryfails the create operation with CMST_INVALID.

Instance Creation and Binding

[5227] DM_CBFAC is used both to create new part instances and to bind toexisting instances by name.

[5228] When i_fac.create is called, the factory checks to see if anexisting instance of the requested part exists. This is accomplished byenumerating the instances through o_fac.get_first and o_fac.get_next.For each instance, the factory compares the value of the <name_prop>property on the instance to the instance name calculated as describedabove.

[5229] If an existing instance is found, the factory increments thecreation reference count property (<c_refcnt_prop>) on the instance andpasses the id back to the caller. If the instance is not found, thefactory creates a new instance and parameterizes it with the appropriateproperty values. The id of the newly created instance is passed back tothe caller.

[5230] The factory does not keep any state itself-it expects thereference counts and other information to be contained as properties onthe created instances.

Reference Counting

[5231] All operations invoked through the i_fac terminal (except thequery operations) are subject to reference counting.

[5232] When an instance is first created the creation reference count(<c_refcnt_prop >) is initialized to one. Every time thereafter,whenever the factory binds to the same instance, it increments thereference count by one. On destruction, the factory decrements thereference count by one. When the reference count reaches zero, theinstance is finally destroyed.

[5233] Activation and deactivation of instances follow the samereference counting procedure defined above. Each time an instance isactivated/deactivated the activation reference count (<a_refcnt_prop>)is incremented/decremented respectively. The instance is onlydeactivated when the reference count reaches zero.

[5234] The reference counting along with instance binding allows thefactory to manage singleton parts—parts that can only be instantiatedonce.

[5235] Depending on how the factory is used, it is possible toinstantiate a class more than once and assign unique names to eachinstance. The use cases below describe this type of situation.

Use Cases

[5236]FIG. 149 illustrates a usage of the DM_CBFAC factory interfaceadapter.

Enforcing One-time Part Instantiation (singletons) by Enforced ClassName

[5237] This use case pertains to parts that may only be instantiatedonce. Subsequent instantiation attempts result in the factory binding tothe existing instance, thus preventing multiple instantiations. In thiscase, the_class_name of the singleton part class is specified throughthe dflt class name property on the factory.

[5238] 1. The structure in the above diagram is created and connected.

[5239] 2. DM_CBFAC is parameterized with the following:

[5240] a. force_dflt_class=TRUE

[5241] b. dflt_class_name=name of singleton part class

[5242] 3. The structure in the above diagram is activated.

[5243] 4. Some time later, MyPart needs to create a singleton part.MyPart invokes fact.create specifying a NULL part name(B_A_FACT.namep=NULL).

[5244] 5. DM_CBFAC tries to bind to an existing instance using theinstance name <dflt_class_name>. The binding fails so DM_CBFAC creates anew instance (through o_fac.create) and parameterizes it with theappropriate values (through o_prp.set). The construction reference countis now one.

[5245] 6. MyPart activates the singleton through fact.activate passingthe instance id returned from fact.create. The singleton is activated(through o_fac.activate) and the activation reference count becomes one.

[5246] 7. Some time later, MyPart may try to create another instance ofthe same part class specified in <dflt_class_name>. MyPart invokesfact.create specifying a NULL part name (B_A_FACT.namep=NULL). instance(through o_fac.create) and parameterizes it with the appropriate values(through o_prp.set). The construction reference count is now one.

[5247] 6. MyPart activates the singleton through fact.activate passingthe instance id returned from fact.create. The singleton is activated(through o_fac.activate) and the activation reference count becomes one.

[5248] 7. Some time later, MyPart may try to create another instance ofthe same part class. MyPart invokes fact.create specifying the partclass name in B_A_FACT.namep.

[5249] 8. DM_CBFAC binds to the existing instance and increments theconstruction reference count by one. DM_CBFAC passes the instance idback to MyPart.

[5250] 9. MyPart activates the singleton through fact.activate passingthe instance id returned from fact.create. Since the singleton isalready active, DM CBFAC increments the activation reference count andreturns.

[5251] 10. Steps 7-9 may be repeated several times.

[5252] 11. Some time later, MyPart needs to deactivate and destroy theinstances created in the steps above. MyPart calls fact.deactivate andfact.destroy for all instances.

[5253] 12. DM_CBFAC decrements the activation and construction referencecounts by one on each call to fact.deactivate and fact.destroyrespectively. As soon as the reference counts reach zero, the factorydeactivates and destroys the singleton.

[5254] Note that specifying a NULL instance name in B_A_FACT.namep oni_fac.create is invalid and DM_CBFAC will fail the operation withCMST_INVALID. In this case an instance name must be provided at alltimes.

Enforcing One-time Part Creation (singletons) on a Per Instance Basis

[5255] Sometimes it is useful to instantiate a single part classmultiple times while assigning unique names to each instance andenforcing only one instantiation of each instance through i_fac. Forexample, some device drivers may handle many similar devices using thesame part class but only allow one instance of each device to beinstantiated at any time.

[5256] In this situation, the part class being created usually exposesseveral properties that identifies what the instance is used for.

[5257] The steps below describe this type of situation:

[5258] 1. The structure in the above diagram is created and connected.

[5259] 2. DM_CBFAC is parameterized with the following:

[5260] a. force_dflt_class=TRUE

[5261] b. dflt_class_name=name of part class to create

[5262] 3. The structure in the above diagram is activated.

[5263] 4. Some time later, MyPart needs to create an instance ofdflt_class_name. MyPart invokes fact.create specifying a unique name forthe instance in B_A_FACT.namep.

[5264] 5. DM_CBFAC tries to bind to an existing instance using theinstance name specified in the bus. The binding fails so DM_CBFACcreates a new instance (through o_fac.create) and parameterizes it withthe appropriate values (through o_prp.set). The instance name is thename specified in the B_A_FACT bus. The construction reference count isnow one.

[5265] 6. MyPart parameterizes the instance according to its specificneeds. It may have a separate property terminal that connects directlyto the DM_ARR property terminal for the means of parameterization.

[5266] 7. MyPart activates the instance through fact.activate passingthe instance id returned from fact.create. The instance is activated(through o_fac.activate) and the activation reference count becomes one.

[5267] 8. Steps 4-7 may be repeated many times-each time MyPart suppliesa unique name for each instance. The end result is many instances of thesame part class each identified by a unique instance name.

[5268] 9. Some time later, MyPart may try to create a new instance usinga duplicate name already specified before. DM_CBFAC binds to theexisting instance and increments the construction reference count byone. DM_CBFAC passes the instance id back to MyPart.

[5269] 10. MyPart activates the instance through fact.activate passingthe instance id returned from fact.create. Since the instance is alreadyactive, DM_CBFAC increments the activation reference count and returns.

[5270] 11. Steps 9-10 may be repeated several times.

[5271] 12. Eventually, MyPart needs to deactivate and destroy all theinstances created in the steps above. MyPart calls fact.deactivate andfact.destroy for each instance.

[5272] 13. DM_CBFAC decrements the activation and construction referencecounts by one (for each instance) on each call to fact.deactivate andfact.destroy respectively. As soon as the reference counts reach zero,the factory deactivates and destroys the instances.

ZP_E2FAC—Event to Factory Adapter

[5273]FIG. 150 illustrates the boundary of the inventive ZP_E2FAC part.

[5274] ZP_E2FAC is a plumbing part that converts incoming events (i.e.,I_DRAIN interface) to part factory operations (i.e., I_FACT interface).

[5275] ZP_E2FAC is parameterized with the event IDs that correspond toeach factory operation. When the specified event is received on its ctlterminal, ZP_E2FAC generates a factory operation out through its facterminal. ZP_E2FAC returns ST_NOT_SUPPORTED for all unrecognized events.

[5276] ZP_E2FAC can be used in front of the part array to controldynamic creation/destruction of parts based on a set of events.

[5277] The ZP_E2FAC's input terminals are not guarded. It does not keepany state so the part can be reentered or used at interrupt context.Note that if the order of the factory operations is of any significancean external event serialization may be required.

[5278] 6. Boundary

[5279] 6.1. Terminals

[5280] Terminal “ctl” with direction “In” and contract I_DRAIN. Note:Input terminal for the events corresponding to the part factoryinterface.

[5281] Terminal “fac” with direction “Out” and contract I_FACT. Note:Output part factory terminal. This terminal is used to create, destroyand enumerate part instances.

[5282] 6.2. Properties

[5283] Property “create_ev” of type “uint32”. Note: Specifies the eventID received on the ctl terminal that results in ZP_E2FAC creating a partinstance out its fac terminal. The value of this property cannot beEV_NULL. This property is mandatory.

[5284] Property “destroy_ev” of type “uint32”. Note: Specifies the eventID received on the ctl terminal that results in ZP_E2FAC destroying apart instance out its fac terminal. The value of this property cannot beEV_NULL. This property is mandatory

[5285] Property “activate_ev” of type “uint32”. Note: Specifies theevent ID received on the ctl terminal that results in ZP_E2FACactivating a part instance out its fac terminal. When the value isEV_NULL, the part instance is activated automatically followingsuccessful creation. The default value is EV_NULL.

[5286] Property “deactivate_ev” of type “uint32”. Note: Specifies theevent ID received on the ctl terminal that results in ZP_E2FACdeactivating a part instance out its fac terminal. When the value isEV_NULL, the part instance is deactivated automatically beforedestruction. The default value is EV_NULL.

[5287] Property “enum_get_first_ev” of type “uint32”. Note: Specifiesthe event ID received on the ctl terminal that results in ZP_E2FACresetting its enumeration state and returning the first part instanceid. When the value is EV_NULL, ZP_E2FAC does not support part instanceenumeration. The default value is EV_NULL.

[5288] Property “enum_get_next_ev” of type “uint32”. Note: Specifies theevent ID received on the ctl terminal that results in ZP_E2FACenumerating the next part instance. When the value is EV_NULL, ZP_E2FACdoes not support part instance enumeration. The default value isEV_NULL.

[5289] Property “gen_id” of type “uint32”. Note: Boolean. If TRUE, thepart instance ID returned on the ‘create’ event is generated by thecreate operation on ZP_E2FAC's fac output. If FALSE, the ‘create’ eventcontains the ID to use when creating the part. The default value isTRUE.

[5290] Property “id.offs” of type “sint32”. Note: Offset of storage inevent bus received on the ctl terminal for part instance ID. If thisvalue is >=0, the offset is from the beginning of the event. If thisvalue is <0, the offset is from the end of the event (−1 specifies thelast byte). The default value is 0×0 (beginning of the event)

[5291] Property “id.sz” of type “uint32”. Note: Size in bytes of partinstance ID. This property can be between one and sizeof (uint32). Thedefault value is sizeof (uint32).

[5292] Property “id.sgnext” of type “uint32”. Note: Boolean. If TRUE,part instance IDs less than four bytes are sign extended. The defaultvalue is FALSE.

[5293] Property “dflt_class_name” of type “asciz”. Note: The class nameto use when creating part instances in case the class name is notprovided with the ‘create’ event. If the value of this property is notan empty string, class_name.xxx properties are used in order to extractthe class name from the property bus. The default value is“”

[5294] Property “class_name.offs” of type “sint32”. Note: Specifies theoffset in the create_ev event bus, received on the ctl terminal, of theclass name to use when creating part instances. If this value is >=0,the offset is from the beginning of the event. If this value is <0, theoffset is from the end of the event (−1 specifies the last byte). If thevalue in the bus is NULL or data is an empty string, the class namespecified by the dflt_class_name property is used. The default value issizeof (uint32)—right after the default part instance ID.

[5295] Property “class_name.by_ref” of type “uint32”. Note: Boolean. IfTRUE, the data at class_name.offs contains a pointer, to the class namestring. If the pointer found in the bus is NULL, the class namespecified by the dflt_class_name property is used. If FALSE, the classname is contained in the event bus. The default value is FALSE.

[5296] Property “ctx.offs” of type “sint32”. Note: Offset of storage inevent bus, received on the ctl terminal, for instance enumerationcontext. If this value is >=0, the offset is from the beginning of theevent. If this value is <0, the offset is from the

[5297] 8. Specification

[5298] 9. Responsibilities

[5299] 1. Sign extend part instance IDs with size less than four byteswhen sign extending is allowed.

[5300] 2. Upon ‘create instance’ event and gen_id property not TRUE,invoke create operation out the fac terminal allowing the connected partto generate the instance IDs. Copy the generated ID back in the eventbus.

[5301] 3. Upon ‘create instance’ event and gen_id property TRUE, use thepart instance ID provided with the incoming event when invoke createoperation out the fac terminal.

[5302] 4. Extract the part instance ID from the event bus and invoke thecorresponding I_FACT operation out the fac terminal when ‘destroy’,‘activate’, and ‘deactivate’ events are received.

[5303] 5. Activate the part instance following successful creation ifthe activate_ev property is EV_NULL.

[5304] 6. Deactivate the part instance before destruction if thedeactivate_ev property is EV_NULL.

[5305] 7. Get first instance id when enum_get_first_ev is received.

[5306] 8. Get next instance id when enum_get_next_ev is received.

[5307] 9. Disallow self-owned buses for creation events when gen_idproperty is TRUE.

[5308] 10. Return status ‘not supported’ for all unrecognized events.

[5309] 10. External States

[5310] None

[5311] 11. Use Cases

[5312] 11.1. Explicit Activation and Deactivation

[5313] The user of ZP_E2FAC has set the activate_ev and deactivate_evproperties to non-zero values.

[5314] 1. ZP_E2FAC receives create_ev on its ctl terminal generally passevents through to other parts. Eventually, all events reach consumersand get released.

[5315] Implementations that are mixtures between transporters andconsumers need to take about proper resource handling whenever the eventis consumed.

[5316] Note that the bus for this interface is CMEVENT_HDR. In C++ thisis equivalent to a CMEvent-derived class.

List of Operations

[5317] Name Description raise Raise an event, such as request,notification, etc. Attribute Definitions CMEVT_A_NONE No attributesspecified. CMEVT_A_AUTO Leave it to the implementation to determine thebest attributes. CMEVT_A_CONST Data in the event bus is constant.CMEVT_A_SYNC Event can be distributed synchronously. CMEVT_A_ASYNC Eventcan be distributed asynchronously. All events that are asynchronous musthave self- owned event buses. See the description of theCMEVT_A_SELF_OWNED attribute below. CMEVT_A_SYNC_(—) Event can bedistributed either synchronously or ANY asynchronously. This is aconvenience attribute that combines CMEVT_A_SYNC and CMEVT_A_ASYNC. Ifno synchronicity is specified, it is assumed the event is bothsynchronous and asynchronous. CMEVT_A_SELF_(—) Event bus was allocatedfrom heap. Recipient of OWNED events with this attribute set aresupposed to free the event. CMEVT_A_SELF_(—) Data in the bus structureis self contained. The CONTAINED event bus contains no externalreferences. CMEVT_A_DFLT Default attributes for an event bus(CMEVT_A_(—) CONST and CMEVT_A_SYNC).

[5318] Bus Definition // event header typedef struct CMEVENT_HDR {uint32 sz; // size of the event data _id id; // event id fig32 attr; //event attributes } CMEVENT_HDR;

[5319] Note Use the EVENT and/or EVENTX macro to conveniently defineevent structures. raise Description: Raise an event (such as request,notification, etc.) In: sz Size of event bus, incl. event-specific data,in bytes id Event ID attr Event attributes [CMEVT_A_XXX] (any Depends onid other) Out: void Return Varies with the event Status: Example: /*define my event */ EVENTX (MY_EVENT, MY_EVENT_ID, CMEVT_(—) A_AUTO,CMEVT_UNGUARDED) dword my_event_data; Remarks: The I_DRAIN interface isused to send events, requests or notifications. It only has oneoperation called raise. An event is generated by initializing an eventbus and invoking the raise operation. The event bus describes the event.The minimum information needed is the size of the bus, event ID, andevent attributes. The binary structure of the event bus may be extendedto include event- specific information. Extending the event busstructure is done by using the EVENT and EVENTX macros. Parts that don'trecognize the ID of a given event should interpret only the commonheader: the members of CMEVENT_HDR. The event attributes are dividedinto two categories: generic and event-specific. The first 16 bits (lowword) of the attribute bit area is reserved for event- specificattributes. The last 16 bits (high word) of the attribute bit area isreserved for generic attributes. These are defined by CMAGIC.H(CMEVT_A_XXX). The generic attributes include the synchronicity of theevent, whether the event data is constant, and if the event bus isself-owned or self-contained. If the event bus is self-owned, this meansthat it was allocated by the generator of the event and it is theresponsibility of the recipient to free it (if the event is consumed).If the event is self-contained, this means the event bus contains noexternal references. For the event to be distributed asynchronously, theevent bus must be self-owned and self-contained. See also: EVENT, EVENTX

I_ITEM—Single Data Item Access Overview

[5320] This interface is dedicated to a single item access based on adata path—a string that uniquely identifies the piece of data that isbeing accessed. This data can be stored in any type of container; howthe data is stored is unimportant for the interface.

[5321] The set of operations is pretty basic: set, get and remove. Theonly detail that deserves attention is the fact that there is no need to“add” the data. This is implied by the set operation. If the containerdoes not have data under given data path, this data will get there whenset operation (with that path) is executed successfully. In contrast, ifthe container already had data under the path, the existing data willget replaced.

[5322] There is no explicit type information supported by the interface.However, for each piece of data, there is a double word that isassociated with that data. Implementations that need type informationcan use this context for indication of the data type.

[5323] Typical implementation of this interface is by a container partthat allows addressing the data by a string name. The syntax of thatstring is not defined by the interface.

List of Operations

[5324] Name Description get Get an item specified by data path set Setan item specified by data path remove Remove an item specified by datapath

Bus Definition

[5325] BUS (B_ITEM) dword qry_hdl; // query handle char *pathp; // datapath void *stgp; // pointer to storage uint32 val_len; // length ofvalue in storage uint32 stg_sz; // size of storage dword ctx; //external data item context dword attr; // attributes END_BUS

[5326] get Descrip- Get an item specified by data path tion: In: qry_hdlHandle to query or 0 to use absolute path pathp Data path(zero-terminated) If qry_hdl != 0 then the data path starts from thecurrent query position. If qry_hdl == 0 then data path starts from theroot. stgp Pointer to buffer for data or NULL to get only the size ofthe item stg_sz Size of buffer pointed to by stgp attr Reserved, must bezero Out: (*stgp) Data for specified data path (if stgp != NULL) val_lendata size (even if stgp == NULL) ctx data context (even if stgp == NULL)Return CMST_OK The operation was successful. Status: CMST_BAD_(—) Thedata path is invalid. SYNTAX CMST_(—) The query handle is invalid.INVALID CMST_NOT_(—) No data found at specified data path or the FOUNDpath was not found. CMST_(—) Storage buffer too small OVERFLO stgpPointer to buffer with data or NULL for no data val_len Length of datactx Data context attr Reserved, must be zero Out: void Return CMST_OKThe operation was successful Status: CMST_(—) The query handle isinvalid. INVALID CMST_BAD_(—) The data path is improperly formed. SYNTAXCMST_NO_(—) Too many names and/or too many entries ROOM Example: B_ITEMitembus; char buffer [256]; cmstat status /* initialize buffer withfirst customers name */ strcpy (buffer, “John Stewart”); /* initializeitem bus */ itembus.qry_hdl = 0; itembus.pathp = “customer[0].name”;itembus.stgp = buffer; itembus.val_len = strlen (buffer) + 1; // include\0 itembus.ctx = MY_STRING_TYPE; // used as type itembus.attr = 0; /*set item data for ‘customer[0].name’ */ status = out (item, set,&itembus); Remarks: If an item is set by using the set operation and thedata path specified does not exist, it will be created. It is possibleand valid to have a data path with item size 0. In this case the contextvalue is still present. To delete an item, use the remove operation. SeeAlso: DM_REP, I_QUERY, EV_REP_NFY_DATA_CHANGE

[5327] remove Descrip- Remove an item specified by data path tion: In:qry_hdl Handle to query or 0 pathp Data path (ASCIIZ zero-terminated) Ifqry_hdl != 0 then the data path starts from the current query position.If qry_hdl == 0 then data path starts from the root. attr Reserved, mustbe zero Out: void Return CMST_OK The operation was successful. Status:CMST_(—) The query handle is INVALID invalid. CMST_BAD_(—) The specifiedpath is invalid or SYNTAX improperly specified. CMST_NOT_(—) No datafound at specified path FOUND Example: B_ITEM itembus; cmstat status; /*initialize item bus */ itembus.qry_hdl = 0; itembus.pathp =“customer[0].name”; itembus.attr = 0; /* remove path ‘customer[0].name’*/ status = out (item, remove, &itembus); See Also: DM_REP, I_QUERY,EV_REP_NFY_DATA_CHANGE

I_LIST—Data List Access Overview

[5328] I_LIST interface is devised to maintain lists. A list in thiscontext is a collection of data objects with a notion of “previous” and“next” given an object. For all elements of the list this notion defineswhich element is preceding the current and which element is next.Naturally, the first and the last elements do not have previous andnext, respectively.

[5329] A O-terminated string uniquely identifies each list element. Theimplementer defines the syntax of this string.

[5330] The basic set of operations defined in this interface allows tosimply add or remove elements from the list or to insert element at aparticular position in the list. This position is identified by areference element and the interface allows insertion before/after thereference or at beginning/end of the list.

[5331] The interface supports both dynamic and static lists, thusallowing implementers to choose their best complexity/performancetrade-off level.

[5332] One typical implementation of a list is an array. In this case isimportant to understand that recycling of deleted elements is almostalways necessary for reasonable behavior. This is a typical scenario instatic list implementations. For dynamic lists, the best-suitedimplementation model is dynamically allocated array with pointers toprevious and next in the list elements (a double-linked list).

[5333] More sophisticated implementers may choose to carry pointers tolast element and/or “recycle list”—a list of deleted array elements.

[5334] The examples below assume hierarchical data implementation butthis is only for illustration purposes. The nature of data is notdefined by the interface.

List of Operations

[5335] Name Description add Add a new element to a list remove Remove anelement from a list Bus Definition BUS (B_LIST) dword qry_hdl; // queryhandle char *pathp; // data path char *bufp; // pointer to storagesize_t buf_sz; // size of storage dword attr; // attributes END_BUS

[5336] add Description: Add a new element to a list In: qry_hdl Handleto query or 0 to pathp use absolute path Subpath of list to add to. Ifqry_hdl == 0 then pathp starts from the root and ends before the index(e.g., company[1]. phone if you want to add a new phone entry undercompany[1]). If qry_hdl ! = 0 then pathp starts from the current queryposition. bufp Pointer to buffer for new path of element or NULL buf_szSize of the buffer pointed to by bufp attr Reserved, must be zero Out:(*bufp) New path for list element (e.g., company[1].phone[3]) ReturnCMST_OK The operation was successful Status: CMST_INVALI The queryhandle is invalid. D CMST_BAD_S The data path is improperly formed.YNTAX CMST_NO_RO Too many entries, OM names or list elements CMST_OVERFToo many levels in the path LOW Example: B_LIST listbus; char path[256]; cmstat status; /* initialize list bus */ listbus.qry_hdl = 0;listbus.pathp = “customer”; listbus.bufp = path; listbus.buf_sz = sizeof(path); listbus.attr = 0; /* add new element to customer list */ status= out (list, add, &listbus); if (status 1= CMST_OK) return; /* print newelement */ printf (“New list element added is %s\n”, path); Remarks Addoperates on a single data path which is either explicitly provided or isthe current data path of a query. To operate on the current data path ofa query, a query handle needs to be supplied. See the I_QUERY interfacefor more information about queries. See Also: DM_REP, I_QUERY,EV_REP_NFY_DATA_CHANGE

[5337] remove Description: Remove an element from a list In: qry_hdlHandle to query or 0 pathp Subpath of element root to remove (e.g.,company [1].forms[4]) Out: void Return CMST_OK The operation wassuccessful Status: CMST_INVALI The query handle is invalid. D CMST_BAD_SThe data path is improperly formed. YNTAX CMST_NOT_F No such listelement (this status OUND will be returned if and only if there is nosuch element; CMST_OK will be returned if the element existed, even ifthere were no data below it). Example: B_LIST listbus; cmstatstatus; /*initialize list bus */ listbus.qry_hdl = 0; listbus.pathp =“customer[0]”; /* remove first element from customer list */ status =out (list, remove, &listbus); Remarks: Remove operates on a single datapath or the current data path of a query. To operate on the current datapath of a query, a query handle needs to be supplied. See the I_QUERYinterface for more information about queries. In hierarchical dataspaces, when this operation succeeds, it is expected that the wholesubtree of the specified path was removed, too. See Also: DM_REP,I_QUERY, EV_REP_NFY_DATA_CHANGE

I_QUERY—Data Queries Overview

[5338] The I_QUERY interface is designed for performing queries amongstring elements. A query string is specified when opening a query;matching items can be enumerated.

[5339] This interface does not define the query string syntax, nor thepossible syntax of the items themselves; this is left to the part thatimplements the interface. A few examples are: query is a SQL string,items are comma-separated values matching the query; query is a filepath with wildcards, items are file names that match the wildcard.

[5340] When a query is opened, the open operation returns two values: aquery handle and an enumeration context. The handle should be providedon all subsequent operations, including close. The enumeration contextis slightly different; again, it should be provided to all operations.The difference is that the enumeration operations can modify the contextvalue; the next time an operation is called, the caller must provide thenew value.

[5341] This mechanism allows for two principally differentimplementations of the interface; provided that callers comply with theinterface specification, they don't need to know which mechanism isimplemented.

[5342] The first mechanism, identifying the query by handle, is usedwhen the implementation can and needs to keep state of the query; oneach operation, the handle identifies the query among the currentlyopened queries.

[5343] The second mechanism, via enumeration context that is modified byeach enumeration operation is used by simple implementations. Forexample, the context may be the index of last item retrieved; this way,when asked for the next item, the implementation just needs to returnthe item at the next index. Note that each operation leaves the contextin the interface bus, so callers don't have to take special actions topass the context on every operation.

List of Operations

[5344] Name Description open Open a query close Close a query get_firstFind first match get_next Find next match get_prey Find previous matchget_last Find last match get_curr Get current match

Bus Definition

[5345] BUS (B_QUERY) char *stgp; // storage buffer size_t stg_sz; //storage buffer size dword qry_hdl; // query handle dword attr; // queryattributes dword qry_ctx; // query context END_BUS

Notes

[5346] Every open query has a query context represented and accessed bya query handle. This context may just be the position in the enumerationor may contain other implementation specific data. Implementations maysupport different numbers of simultaneously open queries. This numberranges from 1 to unlimited.

[5347] open Description: Open a new query In: stgp Query syntax stringThe syntax of the query is not defined by this interface; it is definedby the implementation. attr Attributes, must be 0 The enumerationcriteria is not defined by this interface; it's defined by theimplementation. Out: qry_hdl Query handle Return CMST_OK The operationwas successful Status: CMST_BAD_SYN Invalid query syntax TAX CMST_NO_ROOToo many open queries M Example: B_QUERY qrybus; cmstat Status; /*initialize query bus */ qrybus.stgp = “*”; // enumerate everythingqrybus.attr = 0; /* open query */ status = out (query, open, &qrybus);if (status != CMST_OK) return; /* execute other query operations . . .*/ See Also: DM_REP

[5348] close Description: Close a query in: qry_hdl Query handlereturned from attr a previous call to open Reserved, must be zero Out:qry_hdl 0 Return none Status: Example B_QUERY qrybus; cmstat status; /*initialize query bus */ qrybus.stgp = “*”; // enumerate everythingqrybus.attr = 0; /* open query */ status = out (query, open, &qrybus);if (status != CMST_OK) return; /* execute other query operations . . .*/ /* close query */ out (query, close, &qrybus); See Also: DM_REP

[5349] get_first Description: Find the first match in the given queryIn: qry_hdl Query handle returned from stgp a previous call to openPointer to buffer for the match found or NULL stg_sz Size of the bufferpointed to by stgp attr Reserved, must be zero Out: (*stgp) Result (ifstgp != NULL), in ASCIIZ form qry_ctx Query context Return CMST_OK Theoperation was successful. Status: CMST_INVALID The query handle isinvalid. CMST_OVERFLO Buffer is too small to hold match. W (if stgp !=NULL) CMST_NOT_FO No match was found. UND Example: B_QUERY qrybus; charbuffer [256]; cmstat status; /* initialize query bus */ qrybus.stgp =“*”; // enumerate everything qrybus.attr = 0; /* open query */ status =out (query, open, &qrybus); if (status != CMST_OK) return; /* get firstmatch */ qrybus.stgp = buffer; qrybus.stgsz = sizeof (buffer); status =out (query, get_first, &qrybus); if (status == CMST OK) /* print match(assuming match syntax is a string) */ printf (“The first match of thequery is %s\n”, buffer); /* close query */ out (query, close, &qrybus);See Also: DM_REP

[5350] get_next Description: Find the next match in the given query In:qry_hdl Query handle returned from a stgp previous call to open Pointerto buffer for the match found or NULL stg_sz Size of the buffer pointedto by stgp qry_ctx Query context returned from a previous call toget_xxx attr Reserved, must be zero Out: (*stgp) Result (if stgp !=NULL) qry_ctx Query context Return CMST_OK The operation was successful.Status: CMST_INVALI The query handle is invalid. D CMST_OVERF The bufferis too small to hold the LOW match. (if stgp != NULL) CMST_NOT F Nomatch found OUND Example: B_QUERY qrybus; char buffer [256]; cmstatstatus; /* initialize query bus */ qrybus.stgp = “*”; // enumerateeverything qrybus.attr = 0; /* open query */ status = out (query, open,&qrybus); if (status != CMST_OK) return; /* initialize bus get firstmatch */ qrybus.stgp = buffer; qrybus.stg_sz = sizeof (buffer); /*enumerate matching entries */ for (status = out (query, get_first,&qrybus); status = = CMST_OK; status = out (query, get_next, &qrybus)) {/* print matching entries */ printf (“The next match is %s\n”, buffer);} if (status != CMST_NOT_FOUND) /* print error . . . */ /* close query*/ out (query, close, &qrybus); See Also: DM_REP

[5351] get_prev Description: Find the previous match in the given queryIn: qry_hdl Query handle returned from a previous call to open stgpPointer to buffer for the match found or NULL stg_sz Size of the bufferpointed to by stgp qry_ctx Query context returned from a previous callto get_xxx attr Reserved, must be zero Out: (*stgp) Result (if stgp !=NULL) qry_ctx Query context Return CMST_OK The operation was successfulStatus: CMST_INVALI The query handle is invalid. D CMST_OVERF The bufferis too small to hold the LOW match. (if stgp != NULL) CMST_NOTF No matchfound OUND Example: See get_next example See Also: DM_REP

[5352] get_last Description: Find the last match in the given query In:qry_hdl Query handle returned from a previous call to open stgp Pointerto buffer for the match found or NULL stg_sz Size of the buffer pointedto by stgp attr Reserved, must be zero Out: (*stgp) Result (if stgp !=NULL) qry_ctx Query context Return Status: CMST_OK The operation wassuccessful CMST_(—) The query handle is invalid. INVALID CMST_(—) Thebuffer is too small to hold the match. OVER- (if stgp != NULL) FLOWCMST_(—) No match found NOT_(—) FOUND Example: See get_first example SeeAlso DM_REP

[5353] get_curr Descrip- tion: Get current match in the given query In:qry_hdl Query handle returned from a previous call to open stgp Pointerto buffer for the match found or NULL stg_sz Size of the buffer pointedto by stgp qry_ctx Query context returned from a previous call toget_xxx attr Reserved, must be zero Out: (*stgp) Result (if stgp !=NULL) qry_ctx Query context Return CMST_OK The operation was successfulStatus: CMST_INVALID The query handle is invalid. CMST_OVERFLOW Thebuffer is too small to hold the match. (if stgp != NULL) CMST_NOT_(—) Nomatch found FOUND Example: B_QUERY qrybus; char buffer [256]; cmstatstatus; /* initialize query bus */ qrybus.stgp = “*”; // enumerateeverything qrybus.attr = 0; /* open query */ status = out (query, open,&qrybus); if (status != CMST_OK) return; /* get first match */qrybus.stgp = buffer; qrybus.stg_sz = sizeof (buffer); status = out(query, get_first, &qrybus); if (status != CMST_OK) { /* close query */out (query, close, &qrybus); return; } /* get current match */ status =out (query, get_curr, &qrybus); if (status = = CMST_OK)  /* printcurrent match */  printf (“The current match is %s\n”, buffer); /* closequery */ out (query, close, &qrybus); See Also: DM_REP

I_DPATH—Hierarchical Data Path Arithmetic Overview

[5354] The I_DPATH interface is designed for manipulation of data paths.A data path is a string, with a specific syntax, that identifies a dataitem in some type of data storage. The syntax of data paths manipulatedby this interface is virtually identical to the syntax of accessing datastructures in most high level programming languages, including C andC++.

[5355] Here are a few examples of data path manipulated by thisinterface:

[5356] customer[1].name

[5357] Sensor.Value

[5358] matrix[1][2][3]

[5359] This interface provides for parsing and constructing data paths.The smallest unit of the path we call pel, or path element. Thisinterface defines the following types of path elements:

[5360] names (e.g., Sensor)

[5361] indices (e.g., [3])

[5362] single pel wildcard (e.g., ? or [?])

[5363] wildcard for any number of pels (e.g., *)

List of Operations

[5364] Name Description join Construct a path from up to three elements,inserting the appropriate delimiters split Split a path at the specifiedlevel in up to three parts split2 Split a path at the specified level inup to two parts get_info parse the path and count the number of levels

Pel Type Definition

[5365] Name Description I_DPATH_PELTYPE_NONE No pel specifiedI_DPATH_PELTYPENAME Name pel (ASCII string) I_DPATH_PELTYPE_INDEX Indexpel I_DPATH_PELTYPE_WILD_1 Wildcard for one pel I_DPATH_PELTYPE_(—)Wildcard for any number of pels WILD_ANY

Bus Definition

[5366] BUS (B_DPATH) char *pathp; // full path size_t path_sz; // sizeof buffer for full path, [bytes] char *pre_pathp; // path prefix (up to& excluding the // pel) size_t pre_path_sz; // size of buffer forprefix, [bytes] uint pel_type; // path element (pel) uint32 pel_val; //value of index pel (when // PELTYPE_INDEX) char *pelp; // pel in stringform (any type) size_t pel_sz; // size of pel string buffer, [bytes]char * post_pathp; // suffix (after the pel) size_t post_path_sz; //size of buffer for suffix, [bytes] dword attr; // attributes (nonedefined) int  level; //level to split at // (<0: count backwards)uint  num_levels; // number of levels in the full path END_BUS

Notes

[5367] The data paths are strings of up to 256 characters, which areconstructed using identifiers and array indices. Both identifiers andindices are referred to as “pels”—short for “path element”.

[5368] The data path syntax is very similar to the syntax for specifyingdata structures in programming languages like C. Here are a few examplesof typical data paths:

[5369] customer[1].name

[5370] Sensor.Value

[5371] matrix[1][2][3]

[5372] join Descrip- Construct a path of up to three elements (prefix +pel + tion: suffix), inserting the appropriate delimiters (pathpunctuation) In: pathp Buffer for resulting path or NULL path_sz Size ofbuffer pointed to by pathp in bytes pre_pathp Path prefix or NULL fornone pel_type Type of pel to insert [I_DPATH_(—) PELTYPE_XXX] pelp Pelname to insert between the prefix and suffix This argument is suppliedonly when pel_type == I_DPATH_(—) PELTYPE_NAME. Any type of single-levelpel can be provided in pelp: wildcard, name, or [index] (index must havethe brackets, otherwise it is interpreted as a name). pel_val Pel valueto insert between the prefix and suffix This argument is supplied onlywhen pel_type == I_DPATH_(—) PELTYPE_INDEX. post_pathp Path suffix orNULL for none attr Reserved, must be zero Out: (*pathp) Resulting path(if pathp != NULL) num_levels Number of levels in resulting path ReturnCMST_OK The operation was successful Status: CMST_BAD_(—) Incorrect pathsyntax in one or SYNTAX more elements CMST_OUT_(—) Invalid pel indexvalue (for OF_RANGE I_DPATH_PELTYPE_INDEX only) CMST_BAD_(—) Resultingpath is not a valid path (e.g., too VALUE long) Example: B_DPATHdpathbus; char path [256]; cmstat status; /* initialize bus to join:customer[1].name */ dpathbus.pathp = path; dpathbus.path_sz = sizeof(path); dpathbus.pre_pathp = “customer”; dpathbus.pel_type =I_DPATH_PELTYPE_INDEX; dpathbus.pel_val = 1; dpathbus.post_pathp =“name”; dpathbus.attr = 0; /* join path elements */ status = out (dpath,join, &dpathbus); if (status == CMST_OK)  /* print result(customer[1].name) */  printf (“The resulting path is %s\n”, path);Remarks: All elements (pre_pathp, pelp, and post_pathp) are optional.The path is to be assembled in a local buffer before being copied into*pathp; therefore in and out buffers can overlap, e.g., pathp can be thesame as pre_pathp. See Also: DM_REP

[5373] split Descrip- tion: Divide a path at the specified level in upto three parts In: pathp Path to split Refer to the notes section actthe beginning of this interface for a further description of the syntaxof paths and pels. pre_pathp Buffer for path prefix or NULL, may overlappathp pre_path_sz Size of prefix buffer in bytes pelp Buffer for pelname or NULL, may overlap pathp pel_sz Size of pel name buffer in bytespost_pathp Buffer for path suffix or NULL, may overlap pathppost_path_sz Size of suffix buffer in bytes level Level at which tosplit When level is negative, the split position is counted from the endof the path. If the path has n levels, the valid values for level are[−n..n−1]. If level < 0, level becomes n-level. attr Reserved, must bezero Out: (*pre_pathp) Path prefix (if pre pathp != NULL), may be anempty string pel_type Type of pel [I_DPATH_PEL_(—) TYPE_XXX] Refer tothe notes section act the beginning of this interface for a furtherdescription of the syntax of paths and pels. (*pelp) Pel name or value(if pelp != NULL) pel_val Pel value (0 if pel_type =!I_DPATH_PELTYPE_INDEX) (*post_(—) Path suffix (if post_pathp != NULL) ,pathp) may be an empty string level Level at which path was split, (> =0) Return CMST_OK The operation was successful. Status: CMST_BAD_(—)Incorrect path syntax. SYNTAX CMST_BAD_(—) The source path has less thanlevel levels. VALUE Example: B_DPATH dpathbus; char prepath [256]; charpostpath [256]; char pel [256]; cmstat status; /* initialize bus tosplit: customer[1].name */ dpathbus.pathp = “customer[1].name”;dpathbus.pre_pathp = prepath; dpathbus.pre_path_sz = sizeof (prepath);dpathbus.pelp = pel; dpathbus.pel_sz = sizeof (pel); dpathbus.post_pathp= postpath; dpathbus.post_path_sz = sizeof (postpath); dpathbus.level =1; dpathbus.attr = 0; /* split path */ status = out (dpath, split,&dpathbus); if (status == CMST_OK)  {  /* print results */  printf(“path prefix = %s\n”, prepath); // ‘customer’  printf (“path pel =%s\n”, pel); // ‘[1]’  printf (“path suffix = %s\n”, postpath); //‘name’ } Remarks: pelp will contain the path element at the positionspecified by level. pre_pathp will contain any part of the path beforethis position, and post_pathp will contain any part after this position.See Also: DM_REP

[5374] split2 Descrip- tion: Divide a path at the specified level intotwo parts In: pathp Path to split Refer to the notes section act thebeginning of this interface for a further description of the syntax ofpaths and pels. pre_pathp Buffer for path prefix or NULL, may overlappathp pre_path_sz Size of prefix buffer in bytes post_pathp Buffer forpath suffix or NULL, may overlap pathp post_path_sz Size of suffixbuffer in bytes level Level at which to split When level is negative,the split position is counted from the end of the path. If the path hasn levels, the valid values for level are [−n..n−1]. If level < 0, levelbecomes n-level. attr Reserved, must be zero Out: (*pre_pathp) Pathprefix (if pre_pathp != NULL), may be an empty string (*post_pathp) Pathsuffix (if post_pathp != NULL) , may be an empty string level Level atwhich path was split, (> = 0) Return CMST_OK The operation wassuccessful Status: CMST_BAD_(—) Incorrect path syntax in source path.SYNTAX CMST_BAD_(—) Source path has less than level levels VALUEExample: B_DPATH dpathbus; char prepath [256]; char postpath [256];cmstat status; /* initialize bus to split: ‘customer[1].name’ */dpathbus.pathp = “customer[1].name”; dpathbus.pre_pathp = prepath;dpathbus.pre_path_sz = sizeof (prepath); dpathbus.post_pathp = postpath;dpathbus.post_path_sz = sizeof (postpath); dpathbus.level = 2;dpathbus.attr = 0; /* split path */ status = out (dpath, split2,&dpathbus); if (status == CMST_OK)  {  /* print results */  printf(“path prefix = %s\n”, prepath); // ‘customer[1]’  printf (“path suffix= %s\n”, postpath); // ‘name’  } See Also: DM_REP

[5375] get_info Descrip- Parse the path and count tion: the number oflevels the path contains In: pathp Path to check or NULL Refer to thenotes section at the beginning of this interface for a furtherdescription of the syntax of paths and pels. attr Reserved, must be zeroOut: num_levels Number of levels in the path, if pathp == NULL 0 isreturned Return CMST_OK The operation was successful Status:CMST_BAD_(—) Incorrect path syntax SYNTAX Example: B_DPATH dpathbus;cmstat status; /* initialize bus */ dpathbus.pathp = “customer[0].name”;dpathbus.attr = 0; /* get information on path */ status = out (dpath,get_info, &dpathbus); if (status == CMST_OK)  {  /* print results */ printf (“Path has %u levels.\n”,  dpathbus.num_levels); // displays 3 } See Also: DM_REP

I_SERIAL—Data Serialization Overview

[5376] The I_SERIAL interface provides for performing transfers betweena primary data store and a secondary data store. For example, it can beused to serialize and deserialize the state of a given object to file.

[5377] The definition of the interface does not define the type of datathat is being serialized, nor the format in which the data is maintainedin either store.

[5378] It does define the possible types of secondary data store: diskfile, registry entry and Windows INI file; it defines where and how thedata is placed in the secondary store.

List of Operations

[5379] Name Description clear Clear the state of the primary store loadLoad the primary store from the specified secondary store (deserialize)save Save the primary store into the specified secondary store(serialize)

Storage Type Definitions

[5380] Name Description I_SERIAL_STG_INI Windows INI fileI_SERIAL_STG_FSPEC File by supplied file path I_SERIAL_STG_FHANDLE Fileby supplied file handle (file is open) I_SERIAL_STG_REGISTRY WindowsRegistry

Bus Definition

[5381] BUS (B_SERIAL) uint stg_type; // storage type dword attr; //attributes char *nmp; // depends on storage type char *sect_nmp; //section name dword  hdl; // depends on storage type END_BUS

Notes

[5382] The implementation of these operations may not support allstorage types. It can return CMST_NOT_SUPPORTED for the storage typesnot supported.

[5383] When using the I_SERIAL_STG_FHANDLE storage type, the file handleshould contain a handle to an open file. The file should be at theposition of where the data is to be saved. After a save operation, thefile position will be at the next byte following the data.

[5384] The file handle type used with the I_SERIAL_STG_FHANDLE storagetype is defined by the implementer (Win32, DOS, etc.). The file handletype must remain consistent with all the I_SERIALIZE operations.

[5385] clear Description: Clear the state of the primary store (emptydata) In: void Out: void Return CMST_OK The operation was successfulStatus: (any other) An intermittent error has occurred Example: B_SERIALserbus; /* clear data */ out (ser, clear, &serbus); See Also: DM_REP

[5386] load Description: Load primary store from persistent storage In:stg_type Storage type, [I_SERIAL_STG_xxx] attr Reserved, must be zeronmp Depends on storage type: I_SERIAL_STG_INI Name of INI file to loaddata from I_SERIAL_STG_FSPEC Full path of file to loadI_SERIAL_STG_REGISTRY Key name in registry to load data from (other) setto NULL sect_nmp Depends on storage type: I_SERIAL_STG_INI Name of INIsection to load data from (other) set to NULL hdl Depends on storagetype: I_SERIAL_STG_FHANDLE File handle I_SERIAL_STG_REGISTRY RegistryKey handle (other) set to 0 If the storage type is I_SERIAL_STG_FHANDLE,the file position is expected to be set at the beginning of theserialized repository data; after the load is complete it will leave thefile position at the byte after the last byte of the repository data.Out: void Return CMST_OK The operation was successful Status:CMST_NOT_FOUND The source from which to load could not be located.CMST_IOERR Could not read data from storage medium CMST_NOT_SUPPORTEDSpecified storage type is not supported Example: B_SERIAL serbus; cmstatstatus; /* initialize serialization bus */ serbus.stg_type =I_SERIAL_STG_FSPEC; serbus.attr = O; serbus.nmp = “C:\\DOS\\MYDATA.BIN”;/* load repository from my binary file */ status = out (ser, load,&serbus); See Also: DM_REP

[5387] save Description: Save primary store to persistent storage In:stg_type Storage type [I_SERIAL_STG_XXX] attr Reserved, must be zero nmpDepends on storage type: I_SERIAL_STG_INI Name of INI section to savedata to I_SERIAL_STG_FSPEC Full path of file to save data toI_SERIAL_STG_REGISTRY Key name in registry to save data to (other) setto NULL sect_nmp Depends on storage type: I_SERIAL_STG_INI Name of INIsection to save data to (other) set to NULL hdl Depends on storage type:I_SERIAL_STG_FHANDLE File handle I_SERIAL_STG_REGISTRY Registry Keyhandle (other) set to 0 When this argument is I_SERIAL_STG_FHANDLE, thedata will be saved starting from the current file position; after saveis complete, it will leave the position at the next byte after the lastbyte of the saved data. Out: void Return CMST_OK The operation wassuccessful Status: CMST_NOT_FOUND The source to which to save the datacould not be located. CMST_IOERR Could not write data to storage mediumCMST_NOT_SUPPORTED Specified storage type is not supported Example:B_SERIAL serbus; cmstat status; /* initialize serialization bus */serbus.stg_type = I_SERIAL_STG_FSPEC; serbus.attr = O; serbus.nmp =“C:\\DOS\\MYDATA.BIN”; /* save repository to a binary file */ status =out (ser, save, &serbus); See Also: DM_REP

I_A_FACT—Part Array Factory Services Overview

[5388] This interface is used to control the life cycle and enumeratethe parts in a part array. The parts are identified by an ID eithergenerated by the array or supplied by the user on creation of a newpart.

[5389] This interface is typically used by a controlling part in adynamic assembly. The controlling part is responsible for maintainingthe container of part instances for the assembly.

[5390] This interface is implemented by DM_ARR.

List of Operations

[5391] Name Description create Create a part instance in the array.destroy Destroy a part instance in the array. activate Activate a partinstance in the array. deactivate Deactivate a part instance in thearray. get_first Get the first part in the part array. get_next Get thenext part in the part array.

Bus Definition

[5392] BUS (B_A_FACT) flg32 attr  ;  // attributes [A_FACT_A_XXX] char *namep ;  // class name for part to create uint32 id  ;  // partinstance id _ctx  ctx  ;  // enumeration context END_BUS

[5393] create Description: Create a part instance in the array. In: attrCreation attributes: A_FACT_A_NONE Not specified. A_FACT_A_USE_ID Usethe ID supplied in id to identify the created part. namep Class name ofthe part to create or NULL to use the default class name. id ID to useif the attribute A_FACT_A_USE_ID is specified. Out: id ID of the createdpart (only if the attribute A_FACT_A_USE_ID is not specified). ReturnCMST_OK The operation was successful. Status: CMST_CANT_BIND The partclass was not found. CMST_ALLOC Not enough memory. CMST_NO_ROOM No moreparts can be created. CMST_DUPLICATE The specified ID already exists(only if the A_FACT_A_USE_ID attribute is specified). (all others)Specific error occurred during object creation. Example: B_A_FACT bus;CMSTAT  s; /* create a new part in the part array */ bus.attr =A_FACT_A_NONE; bus.namep = “MyPartClass”; s = out (i_a_fact, create,&bus); if (s != CMST_OK) . . . See Also: DM_ARR

[5394] destroy Description: Destroy a part instance in the array. In: idID of part to destroy. Out: void Return CMST_OK The operation wassuccessful. Status: CMST_NOT_FOUND A part with the specified ID was notfound. (all others) An intermittent error occurred during destruction.Example: B_A_FACT bus; CMSTAT  s; /* create a new part in the part array*/ bus.attr = A_FACT_A_NONE; bus.namep = “MyPartClass”; s = out(i_a_fact, create, &bus); if (s != CMST_OK) . . . . . . /* destroycreated part */ s = out (i_a_fact, destroy, &bus); if (s != CMST_OK) . .. See Also: DM_ARR

[5395] activate Description: Activate a part instance in the array. In:id ID of part to activate. Out: void Return CMST_OK The operation wassuccessful. Status: CMST_NOT_FOUND A part with the specified ID was notfound. CMST_NO_ACTION The part is already active. CMST_REFUSE Mandatoryproperties have not been set or terminals not connected on the part.(all others) An intermittent error occurred during activation. Example:B_A_FACT bus; CMSTAT  s; /* create a new part in the part array */bus.attr = A_FACT_A_NONE; bus.namep = “MyPartClass”; s = out (i_a_fact,create, &bus); if (s != CMST_OK) . . . /* activate part */ s = out(i_a_fact, activate, &bus); if (s != CMST_OK) . . . See Also: DM_ARR

[5396] deactivate Description: Deactivate a part instance in the array.In: id ID of part to deactivate. Out: void Return CMST_OK The operationwas successful. Status: CMST_NOT_FOUND A part with the specified ID wasnot found. (all others) An intermittent error occurred duringdeactivation. Example: B_A_FACT bus; CMSTAT  s; /* create a new part inthe part array */ bus.attr = A_FACT_A_NONE; bus.namep = “MyPartClass”; s= out (i_a_fact, create, &bus); if (s != CMST OK) . . . /* activate part*/ s = out (i_a_fact, activate, &bus); if (s != CMST_OK) . . . /*deactivate part */ s = out (i_a_fact, deactivate, &bus); if (s !=CMST_OK) . . . See Also: DM_ARR

[5397] get_first Description: Get the first part in the array. In: voidOut: Id ID of the first part in the array. ctx Enumeration context forsubsequent get_next calls. Return CMST_OK The operation was successful.Status: CMST_NOT_FOUND The array has no parts. Example: B_A_FACT bus;CMSTAT  s; /* enumerate all parts in part array */ s = out (i_a_fact,get_first, &bus); while (s == CMST_OK) { /** print id */ printf (“PartID = %x\n”, bus.id); /** get next part */ s = out (i_a_fact, get_next,&bus); } See Also: DM_ARR

[5398] get_next Description: Get the next part in the array. In: ctxEnumeration context from previous get_xxx calls. Out: id ID of next partin the array. ctx Enumeration context for subsequent get_xxx calls.Return CMST_OK The operation was successful. Status: CMST_NOT_FOUND Thearray has no more parts. Example: B_A_FACT bus; CMSTAT  s; /* enumerateall parts in part array */ s = out (i_a_fact, get_first, &bus); while (s== CMST_OK) { /** print id */ printf (“Part ID = %x\n”, bus.id); /** getnext part */ s = out (i_a_fact, get_next, &bus); } See Also: DM_ARR

I_A_CONN—Part Array Connection Services Overview

[5399] This interface is used to connect and disconnect terminals ofparts maintained in a part array. This interface is typically used by acontrolling part in a dynamic assembly. The controlling part isresponsible for maintaining the container of part instances for theassembly.

[5400] This interface is implemented by DM_ARR.

List of Operations

[5401] Name Description connect_(—) Connect two terminals between partsin the array. disconnect Disconnect two terminals between parts in thearray.

Bus Definition

[5402] BUS (B_A_CONN) uint32 id1   ; // id of part 1 char  *terml_namep; // terminal name of part 1 uint32 id2   ; // Id of part 2 char *term2_namep ; // terminal name of part 2 _Id  conn_id   ; //connection id END_BUS

Notes

[5403] When connecting and disconnecting terminals, id1 and id2 may bethe same to connect two terminals on the same part.

[5404] connect Description: Connect two terminals between parts in thearray. In: id1 ID of first part. term 1_namep Terminal name of firstpart. id2 ID of second part. term2_namep Terminal name of second part.conn_id Connection ID to represent this connection. Out: void ReturnCMST_OK The operation was successful. Status: CMST_REFUSE There has beenan interface or direction mismatch or an attempt has been made toconnect a non-activetime terminal when the part is in an active state.CMST_NOT_FO At least one of the UND terminals could not be found or oneof the ids is invalid. CMST_OVERFLO An implementation W imposedrestriction in the number of connections has been exceeded. Example:B_A_CONN bus; CMSTAT s; /* connect “in” on first part to “out” on secondpart */ bus.id1 = part id1; bus.term1_namep = “in”; bus.id2 = part_id2;bus.term2_namep = “out”; bus.conn_id = 1; s = out (i_a_conn, connect_,&bus); if (S != CMST_OK) . . . See Also: DM_ARR

[5405] disconnect Description: Disconnect two terminals between parts inthe array. In: id1 ID of first part. term 1_namep Terminal name of firstpart. id2 ID of second part. term2_namep Terminal name of second part.conn_id Connection ID to represent this connection. Out: void ReturnCMST_OK The operation was successful. Status: Example: B_A_GONN bus;CMSTAT s; /* connect “in” on first part to “out” on second part */bus.id1 = part_id1; bus.term1_namep = “in”; bus.id2 = part_id2;bus.term2_namep =“out”; bus.conn_id = 1; s = out (i_a_conn, connect_,&bus); if (s != CMST_OK) . . . . . . /* disconnect terminals */ out(i_a_conn, disconnect, &bus); See Also: DM_ARR

I_A_PROP—Part Array Property Services Overview

[5406] This interface is used to access properties of parts maintainedby a part array. The interface includes all the standard propertyoperations including enumeration.

[5407] This interface is typically used by a controlling part in adynamic assembly. The controlling part is responsible for maintainingthe container of part instances for the assembly.

[5408] This interface is implemented by DM_ARR.

List of Operations

[5409] Name Description get Get the value of a property from a part inthe array. set Set the value of a property of a part in the array. chkCheck if a property can be set to the specified value. get info Retrievethe type and attributes of the specified property. qry_open Open a queryto enumerate properties on a part in the array based upon the specifiedattribute mask and values. qry_close Close a query. qry_first Retrievethe first property in a query. qry_next Retrieve the next property in aquery. qry_curr Retrieve the current property in a query.

Bus Definition

[5410] BUS (B_A_PROP) uint32 Id  ; // id of the instance that is the //operation target char  *namep  ; // property name [ASCIZ] uint16 type  ;// property type [CMPRP_T_XXX] flg32 attr  ; // attributes [CMPRP_A_XXX]flg32 attr_mask; // attribute mask for queries // [CMPRP_A_XXX] void *bufp  ; // pointer to input buffer uint32 buf_sz  ; // size of *bufpin bytes uint32 val_len  ; //length of value in *bufp in bytes _hdl qryh  ; // query handle END_BUS

Notes

[5411] When opening a new query using qry_open, specifiy the set ofattributes in attr_mask and their desired values in attr. During theenumeration, a bit-wise AND is performed between the actual attributesof each property and the value of attr_mask;

[5412] the result is then compared to attr. If there is an exact match,the property will be enumerated.

[5413] To enumerate all properties of a part, specifiy the query stringas “*” and attr_mask and attr as 0.

[5414] get Description: Get the value of a property from a part in thearray. In: id Part instance ID. namep Null-terminated property name.type Type of the property to retrieve or CMPRP_T_NONE for any. bufpPointer to buffer to receive property or NULL. buf_sz Size in bytes of*bufp. Out: (*bufp) Property value. val_len Length in bytes of propertyvalue. Return GMST_OK The operation was successful. Status: CMST_NOT_FOThe property could not be UND found or the ID is invalid. CMST_REFUSEThe data type does not match the expected type. CMST_OVERFLO The bufferis too small to hold the W property value. Example: B_A_PROP bus; charbuffer [256]; CMSTAT s; /* get the value of property “MyProp” */ bus.id= part_id; bus.namep = “MyProp”; bus.type = CMPRP_T_ASCIZ; bus.bufp =buffer; bus.buf_sz = sizeof (buffer); s = out (i_a_prop, get, &bus); if(s != CMST_OK) . . . /* print property information */ printf (“The valueof property MyProp is %s\n”, buffer); printf (“The value is %Id byteslong.”, bus.val_len); See Also: DM_ARR

[5415] set Description: Set the value of a property from a part in thearray. In: id Part instance ID. namep Null-terminated property name.type Type of the property to set. bufp Pointer to buffer containingproperty value or NULL (reset the property value to its default).val_len Size in bytes of property value (for string properties this mustinclude the terminating zero). Out: void Return CMST_OK The operationwas successful. Status: CMST_NOT_FO The property could not UND be foundor the ID is invalid. CMST_REFUSE The property type is incorrect or theproperty cannot be changed while the part is in an active state.CMST_OUT_OF_ The property value is not within the RANGE range of allowedvalues for this property. CMST_BAD_AC There has been an attempt to set aCESS read-only property. CMST_OVERFLO The property value is too large. WCMST_NULL_PT The property name R pointer is NULL or an attempt was madeto set default value for a property that does not have a default value.Example: B_A_PROP bus; CMSTAT s; /* set the value of property “MyProp”*/ bus.id = part_Id; bus.namep = “MyProp”; bus.type = CMPRP_T_ASCIZ;bus.bufp = “MyStringValue”; bus.val_len = strlen (“MyStringValue”) + 1;// include NULL // terminator s = out (i_a_prop, set, &bus); if (s !=CMST OK) . . . See Also: DM_ARR

[5416] chk Description: Check if a property can be set to the specifiedvalue. In: id Part instance ID. namep Null-terminated property name.type Type of the property to check. bufp Pointer to buffer containingproperty value. val_len Size in bytes of property value. Out: voidReturn CMST_OK The operation was successful. Status: CMST_NOT_FO Theproperty could not be UND found or the ID is invalid. CMST_REFUSE Theproperty type is incorrect or the property cannot be changed while thepart is in an active state. CMST_OUT_OF_(—) The property value is notwithin the RANGE range of allowed values for this property. CMST_BAD_ACThere has been an attempt to set a CESS read-only property. CMST_OVERPLOThe property value is too large. W CMST_NULL_PT The property name Rpointer is NULL or an attempt was made to set default value for aproperty that does not have a default value. Example: B_A_PROP bus;CMSTAT s; /* check setting the value of property “MyProp” */ bus.id =part_id; bus.namep = “MyProp”; bus.type = CMPRP_T_ASCIZ; bus.bufp =“MyStringValue”; bus.val_len = strien (“MyStringValue”) + 1; // includeNULL // terminator s = out (i_a_prop, chk, &bus); if (s != CMST_OK) . .. See Also: DM_ARR

[5417] get_info Description: Retrieve the type and attributes of thespecified property. In: id Part instance ID. namep Null-terminatedproperty name. Out: type Type of property [CMPRP_T_XXX]. attr Propertyattributes [CMPRP_A_XXX]. Return CMST_OK The operation was successful.Status: CMST_NOT_FO The property could not be UND found or the ID isinvalid. Example: B_A_PROP bus; CMSTAT s; /* set the value of property“MyProp” */ bus.id = part_Id; bus.namep = “MyProp”; s = out (i_a_prop,get_info, &bus); if (s != CMST_OK) . . . /* print property information*/ printf (“The property type is %u.\n”, bus.type); printf (“Theproperty attributes are %x.\n”, bus.attr); See Also: DM_ARR

[5418] qry_open Description: Open a query to enumerate properties on apart in the array based upon the specified attribute mask and values orCMPRP_A_NONE to enumerate all properties. In: id Part instance ID. namepQuery string (must be “*”). attr Attribute values of properties toinclude. attr_mask Attribute mask of properties to include. Can be oneor more of the following values: CMPRP_A_NONE Not specified. CMPRP APERSI Persistent ST property. CMPRP_A_ACTIV Property can be ETIMEmodified while active. CMPRPA_MAND Property must be ATORY set beforeactivation. CMPRP_A_RDONL Read-Only Y property. CMPRP_A_UPCA Forceuppercase. SE CMPRP_A_ARRA Property is an Y array. Out: qryh Queryhandle. Return CMST_OK The operation was successful. Status:CMST_NOT_FOU The ID could not be found or is ND invalid. CMST_NOT_SUPThe specified part does not support PORTED property enumeration or doesnot support nested or concurrent property enumeration. Example: B_A_PROPbus; char buffer [256]; CMSTAT s; /* open query for all properties thatare mandatory */ bus.id = part id; bus.namep = “*”; bus.attr =CMPRP_A_MANDATORY; bus.attr_mask = CMPRP_A_MANDATORY; bus.bufp = buffer;bus.buf_sz sizeof (buffer); s = out (i_a_prop, qry_open, &bus); if (s !=CMST_OK) . . . /* enumerate and print all mandatory properties */ s =out (i_a_prop, qry_first, &bus); while (s == CMST_OK) { /* printproperty name */ printf (“Property name is %s\n”, buffer); /* getcurrent property */ s = out (i_a_prop, qry curr, &bus); if (s !=CMST_OK) . . . /* get next mandatory property */ s = out (I_a_prop,qry_next, &bus); } /** close query */ out (i_a_prop, qry_close, &bus);See Also: DM_ARR

[5419] qry_close Description: Close a query. In: qryh Handle to openquery. Out: void Return CMST_OK The operatiQn was successful. Status:CMST_NOT_FOU Query handle was not found or is ND invalid. CMST_NOT_BUSThe object can not be entered from Y this execution context at thistime. Example: See qry open example. See Also: DM_ARR

[5420] qry_first Description: Retrieve the first property in a query.In: qryh Query handle returned on qry_open. bufp Storage for thereturned property name or NULL. buf_sz Size in bytes of *bufp. Out:(*bufp) Property name (if bufp not NULL). Return CMST_OK The operationwas successful. Status: CMST_NOT_FOUND No properties found matchingcurrent query. CMST_OVERFLOW Buffer is too small for property name.Example: See qry_open example. See Also: DM_ARR

[5421] qry_next Description: Retrieve the next property in a query. In:qryh Query handle returned on qry_open. bufp Storage for the returnedproperty name or NULL. buf_sz Size in bytes of *bufp. Out: (*bufp)Property name (if bufp not NULL). Return CMST_OK The operation wassuccessful. Status: CMST_NOT_FOUND No more properties found matching thecurrent query. CMST_OVERFLOW Buffer is too small for property name.Example: See qry_open example. See Also: DM_ARR

[5422] qry_curr Description: Retrieve the current property in a query.In: qryh Query handle returned on qry_open. bufp Storage for thereturned property name or NULL. buf_sz Size in bytes of *bufp. Out:(*bufp) Property name (if bufp not NULL). Return CMST_OK The operationwas successful. Status: CMST_NOT_FOUND No current property (e.g. after acall to qry_open). CMST_OVERFLOW Buffer is too small for property name.Example: See qry_open example. See Also: DM_ARR

I_EVS, I_EVS_R—Event Source Interfaces Overview

[5423] These two interfaces are for manipulating and using eventsources. I_EVS and I_EVS_R are conjoint interfaces; they are always usedtogether.

[5424] Events generated by an event source can be periodic or singular.Periodic events will be generated in equal intervals of time. Singularevents will be generated when a synchronization object gets signaled orwhen a timeout expires.

[5425] The interface also allows “preview” of the events being generatedand cancellation.

[5426] The I_EVS_R interface has one operation: fire. This operation isinvoked when the event source generates an event.

List of Operations

[5427] Name Description arm Arm the event source (I_EVS) disarm Disarmthe event source (I_EVS) fire Trigger event occurred (I_EVS_R)

Operation Bus

[5428] BUS (B_EVS) flg32  attr; // attributes [EVS_A_xxx] _ctx  ctx ; //trigger context uint32  time; // trigger timeout or period cmstat  stat; // trigger status _hdl  h  ; // synchronization object handle END_BUS

[5429] arm Description: Arm the event source Direction: Input In: attrArm attributes, can be any one of the following: EVS_A_NONE Notspecified. EVS_A_ONETIME Arm for a one-time firing (disarm upon fire)EVS_A_CONTINUOUS Arm for multiple firing (remain armed upon fire)EVS_A_PREVIEW Fire a preview before the actual firing ctx User-suppliedcontext to provide when firing time Timeout or fire period inmilliseconds, this can also be one of the following values:EVS_T_INFINITE Infinite time EVS_T_DEFAULT Implementor-defined default hHandle to a synchronization object (or NO_HDL for none) Out: void ReturnCMST_OK The operation was successful. Status: CMST_NO_ROOM Can not armany more events in the event source. CMST_NO_ACTION Already armed(possibly with different arguments). CMST_REFUSE Event source cannot bearmed manually. CMST_NOT_SUPPORTED The particular combination ofattributes and fields is not supported by the implementor. Example:B_EVS eb; cmstat s; // arm event source for a one-shot timer with nopreview eb.attr = EVS_A_ONETIME; eb.time = 10000; // 10 seconds eb.ctx =0 × 500; s = out (evs, arm, &eb); if (s ! = CMST_OK) . . . Remarks: Thefields attr (not all combinations) and ctx must be supported by allimplementors. Support for all other fields is optional. Bothimplementors and users of this interface must describe theirsupport/requirements in the appropriate documentation. Implementors mayhonor the field time as a timeout or period between firings.Implementors may honor the field h as a handle to a synchronizationobject. Typically, the source will fire either when h is signaled orwhen the timeout expires. It is also possible to use h withEVS_A_CONTINUOUS. Implementors may accept a NULL bus or invalidarguments if the implementor has sufficient defaults. If the bus isNULL, ctx will be 0 on fire. Implementors may ignore most or all of thesupplied arguments (if so configured). As long as the bus is not NULL,ctx should be honored. Exactly one of EVS_A_ONETIME and EVS_A_CONTINUOUSmust be specified; if none is specified, the implementor may use itsdefault (usually with auto-arm). Implementors may support only one ofthese two attributes. If the implementor auto-arms the event source,calling arm/disarm may return CMST_REFUSE, indicating that the eventsource cannot be controlled manually. If EVS_A_PREVIEW is specified, theterminal on which fire is received must be unguarded. Preview is invokedin non- thread context (interrupt or event time in Windows 95/98 KernelMode; DISPATCH IRQL in Windows NT kernel mode). Not all implementorssupport the preview feature. See Also: disarm, fire

[5430] disarm Description: Arm the event source Direction: Input In: ctxUser context - as supplied on arm attr Disarm attributes, must beEVS_A_NONE Out: void Return CMST_OK The operation was successful.Status: CMST_NOT_FOUND An armed event associated with ctx cannot befound. CMST_NO_ACTION The event source is not armed. CMST_REFUSE Theevent source cannot be disarmed manually. Example: B_EVS eb; cmstat s;// disarm event source eb.attr = EVS_A_NONE; eb.ctx = 0 × 500; s = out(evs, disarm, &eb); if (s ! = CMST_OK) . . . Remarks: Upon successfulreturn, the event source guarantees that it will not fire unless it isre-armed. See Also: arm, fire

[5431] fire Description: Trigger event occurred Direction: Output In:attr Fire attributes, can be one of the following: EVS_A_NONE Notspecified. EVS_A_PREVIEW This is a fire preview. ctx User suppliedcontext provided on arm. stat Trigger status, can be one of thefollowing: CMST_OK Event triggered normally. CMST_TIMEOUT Eventtriggered due to timeout. This status can only appear if event sourcewas armed to wait on a synchronous object with a timeout period.CMST_ABORTED Event source was disarmed due to external reason (e.g.,deactivation). This status can only appear if event source was armed towait on a synchronous object with a timeout period. Out: ctx Usersupplied context to provide on the final fire. This is only used if inthe context of a fire preview (attr = = EVS_A_PREVIEW). See the Remarkssection below. Return CMST_OK The event is accepted - to be sent Status:again without the EVS_A_PREVIEW attribute (ignored if not in the contextof a fire preview). (any other) The event is refused - do not send theevent again (ignored if not in the context of a fire preview). Example:B_EVS eb; cmstat s; // arm event source for a one-shot timer with nopreview eb.attr = EVS_A_ONETIME; eb.time = 10000; // 10 seconds eb.ctx =0 × 500; s = out (evs, arm, &eb); if (5 ! = CMST_OK) . . . // firecallback OPERATION (evs_r, fire, B_EVS) { // nb: bp −> ctx should be 0 ×500 - supplied on arm printf (“Event source fired!\n”); return(CMST_OK); } END_OPERATION Remarks: If the event source was armed as aone-time event, the event source is disarmed before fire is called(before preview also). If the event source was armed as a continuousevent, the event source remains armed until disarmed. arm and disarm canbe called from within fire (provided that fire came without theEVS_A_PREVIEW attribute). If EVS_A_PREVIEW is set, the fire call may notbe at thread time. Interrupts may be disabled (Windows 95/98 KernelMode), the CPU may be running at DISPATCH IRQL (Windows NT Kernel Mode),etc. arm and disarm (and any thread-level guarded code) should not becalled from within fire preview. If a recipient expects fire previews,the terminal on which fire is received should be unguarded (or guardedat the appropriate level depending on the event source). Upon returnfrom fire preview, if a recipient modified ctx, the modified ctx will beprovided on the final fire. This change affects only the final fire thatcorresponds to this preview. Subsequent firings (if the event source wasarmed as continuous) will come with the original ctx provided on arm. IfEVS_A_PREVIEW is not set, the return status from a fire call isgenerally ignored. Some event sources may expect CMST_OK for acceptedevents, and any other for refused events (i.e., event not processed bythe recipient). In both cases, the returned status does not affect thearmed/disarmed state of the event source for future firings. See Also:arm, disarm

I_CRT—Critical Section Overview

[5432] This is an interface to a critical section synchronizationobject. It provides operations for entering and leaving the criticalsection. No support for conditional entering is provided (a.k.a.try-enter) by this interface.

List of Operations

[5433] Name Description enter Enter a critical section (cumulative,blocking) leave Leave a critical section (cumulative)

[5434] enter Description: Enter a critical section (cumulative,blocking) In: void Out: void Return CMST_OK The operation wassuccessful. Status: ST_OVERFLOW Critical section entered too many timesExample: cmstat s; // enter critical section s = out (crt, enter, NULL);if (s ! = CMST_OK) . . . Remarks: The calling thread is blocked untilthe critical section is available.

[5435] leave Description: Leave a critical section (cumulative) In: voidOut: void Return CMST_OK The operation was successful. Status: Example:cmstat s; // enter critical section s = out (crt, enter, NULL); if (s != CMST_OK) . . . . . . // leave critical section s = out (crt, leave,NULL); if (s ! = CMST_OK) . . . Remarks: If another thread was waitingfor this critical section, the calling thread may be pre-empted beforeit returns from this call.

I_PRPFAC—Property Factory Interface Overview

[5436] The property factory interface is used to handle virtual(dynamic) properties. Such operations include the creation, destruction,initialization and enumeration of the properties.

List of Operations

[5437] Name Description create Create a new virtual property destroyDestroy a virtual property clear Re-initialize the property value toempty get_first Retrieve first virtual property get_next Retrieve nextvirtual property

Operation Bus

[5438] BUS (B_PRPFAC) char  *namep  ; // property name [ASCIZ] uint16type  ; // property type [CMPRP_T_XXX] flg32 attr  ; // attributes[CMPRP_A_XXX] byte  *bufp  ; // pointer to buffer to receive // propertyname uint32 sz  ; // size of *bufp in bytes uint32 ctx  ; // enumerationcontext END_BUS

[5439] create Description: Create a new virtual property In: namepnull-terminated property name type type of the property to retrieve[CMPRP_T_xxx] attr attributes to be associated with property[CMPRP_A_xxx] Out: void Return CMST_OK successful Status: CMST_INVALIDnamep is empty or “*” CMST_DUPLICATE the property already existsCMST_NULL_PTR namep is NULL CMST_REFUSE no data type providedCMST_NO_ROOM no room to store property CMST_ALLOC failed to allocatememory for property Example: B_PRPFAC bus; cmstat s; // create a newvirtual property bus.namep = “MyProp”; bus.type = CMPRP_T_ASCIZ;bus.attr = CMPRP_A_NONE; s = out (prpfac, create, &bus); if (s !=CMST_OK) . . . // other property operations here . . . // destroyproperty s = out (prpfac, destroy, &bus); if (s != CMST_OK). . .

[5440] destroy Description: Destroy a virtual property In: namepnull-terminated property name to destroy Out: void Return CMST_OKsuccessful Status: CMST_NOT_FOUND the property could not be found ifnamep not NULL CMST_INVALID namep is NULL and all is TRUE CMST_NULL_PTRnamep is NULL Example: See create example. Remarks: if namep is “*” thenall properties will be destroyed

[5441] clear Description: Re-initialize the property value to empty In:namep null-terminated property name Out: void Return CMST_OK successfulStatus: CMST_NOT_FOUND the property could not be found if namep not NULLCMST_INVALID namep is NULL and all is TRUE Example: B_PRPFAC bus; cmstats; // clear vitual property bus.namep = “MyProp”; s = out (prpfac,clear, &bus); if (s != CMST_OK) . . . Remarks: if namep is “*” then allproperties will be re-initialized empty infers zero-initialized value

[5442] get_first Description: Retrieve first property In: bufp buffer toreceive property name sz size of *bufp Out: (*bufp ) null-terminatedproperty name type property type [CMPRP_T_xxx] attr property attributesctx enumeration context Return CMST_OK successful Status: CMST_NOT_FOUNDno properties to enumerate CMST_OVERFLOW buffer too small Example:B_PRPFAC bus; char buf [256]; cmstat s; // enumerate all virtualproperties in container bus.namep = buf; bus.sz = sizeof (buf); s = out(prpfac, get_first, &bus); while (s = = CMST_OK)  {  // print propertyname  printf (“Property name is %s\n”, buf);  // get next property  s =out (prpfac, get_next, &bus);  }

[5443] get_next Description: Retrieve next property In: bufp buffer toreceive property name sz size of *bufp ctx enumeration context Out:(*bufp ) null-terminated property name type property type [CMPRP_T_xxx]attr property attributes ctx enumeration context Return CMST_OKsuccessful Status: CMST_NOT_FOUND no properties to enumerateCMST_OVERFLOW buffer too small Example: See get_first example.

I_BYTEARR—Byte-Array Interface Overview

[5444] This interface provides access to a byte-array. It provides readand write operations for manipulation of the array. It also allowscontrol over the byte-array metrics (size).

[5445] The byte array may be fixed length or it may be dynamic—dependingon the implementation.

List of Operations

[5446] Name Description read read block of bytes starting at specifiedoffset write write block of bytes starting at specified offsetget_metrics get size of the array set_metrics set size of the array

Operation Bus

[5447] BUS (B_BYTEARR) void  *p ; // buffer pointer uint32  offs ; //offset uint32  len ; // length of data in *p, [bytes] uint32  sz ; //size of buffer pointed to by p, // [bytes] flg32  attr ; // attributes,[BYTEARR_A_xxx] END_BUS

[5448] read Description: read block of bytes starting at specifiedoffset In: p buffer point sz size of buffer offs offset len how manybytes to read attr 0 to read < = len bytes, or BYTEARR_A_EXACT to readexactly len bytes Out: *p data len bytes actually read Return CMST_OKsuccessful Status: CMST_EOF cannot read requested len bytes (whenBYTEARR_A_EXACT) Example: B_BYTEARR bus; char buf [256]; cmstat s; //read 5 bytes starting at offset 10 bus.p = buf; bus.sz = sizeof (buf);bus.offs = 10; bus.len = 5; bus.attr = BYTEARR_A_EXACT; s = out (arr,read, &bus); if (s != CMST_OK) . . . Remarks: if BYTEARR_A_EXACT is notspecified, an attempt to read beyond the limits of supported spacereturns CMST_OK with len = = 0.

[5449] write Description: write block of bytes starting at specifiedoffset In: p pointer to data to be written offs offset len how manybytes to write attr 0 to BYTEARR_A_GROW to grow automatically Out: voidReturn CMST_OK successful Status: CMST_OVERFLOW offs + len is beyond thecurrent size of the array and BYTEARR_A_GROW was not specifiedCMST_NOT_(—) specified attribute is not supported SUPPORTED Example:B_BYTEARR bus; char buf [256]; cmstat s; // read 5 bytes starting atoffset 10 strcpy (buf, “12345”); bus.p = buf; bus.offs = 10; bus.len =5; bus.attr = 0; s = out (arr, write, &bus); if (s != CMST_OK) . . .

[5450] get_metrics Description: get size of the array In: void Out: lennumber of bytes available for reading from offset 0 sz number of bytesavailable for writing from offset 0 Return CMST_OK successful Status:Example: B_BYTEARR bus; cmstat s; // get size of the array s = out (arr,get_metrics, &bus); if (s != CMST_OK) . . . // print size printf(“available for reading: %ld\n”, bus.len); printf (“available forwriting: %ld\n”, bus.sz);

[5451] set_metrics Description: set size of the array In: len number ofbytes to become available for reading from offset 0 SZ number of bytesto become available for writing from offset 0 Out: void Return CMST_OKsuccessful Status: CMST_REFUSE if specified sz < specified lenCMST_ALLOC specified size cannot be reached (i.e., out of memory)CMST_NOT_SUPPORTED operation is not supported Example: B_BYTEARR bus;cmstat  s; // set size of the array bus.sz = 10; bus.len = 10; s = out(arr, set_metrics, &bus); if (s != CMST_OK) . . . Remarks: if len <current length, elements are removed if len > current length, elementsare filled with O

I_DEN—Device Enumeration Interface Overview

[5452] This is a device class enumeration interface. Supports multiplequeries (if implementation allows it) on the device class name space.The interface supports multiple class name identifications. Uses UNICODEstrings.

List of Operations

[5453] Name Description qry_open Open a query to enumerate devicesqry_close Close a query qry_first Get the first device qry_next Get thenext device

Operation Bus

[5454] BUS (B_DEN) char  class_name [16]; // CMagic class name WCHAR device_name[64]; // name to use for registering // the device WCHAR sym_link1 [64]; // Win32 alias (does not include // the \??\ prefix)WCHAR sym_link2 [64]; // Win32 alias (does not include // the \??\prefix) uint32  id; // device ID (valid while qry is // open) _hdl qry_h; // query handle END_BUS

[5455] qry_open Description: Open a query to enumerate devices in: voidOut: qry_h query handle; must be passed on subsequent calls qry_first,qry_next, qry_close Return CMST_OK The operation was successful. Status:ST_NO_ROOM no more queries can be open Example: B DEN bus; // open querys = out (den, qry_open, &bus); if (s != CMST_OK) . . . // query alldevices s = out (den, qry_first, &bus); while (s == CMST_OK) { // printinformation printf (“Class name = %s\n”, bus.class_name ); printf (“ID =%Id\n”, bus.id   ); // get next s = out (den, qry_next, &bus); } //close query out (den, qry_close, &bus);

[5456] qry_close Description: Close a query In: qry_h query handle fromqry_open Out: void Return CMST_OK The operation was successful. Status:Example: See qry_open example.

[5457] qry_first/qry_next Description: Get the first/next device In:qry_h Query handle from qry_open Out: class_name ClassMagic class nameof the part that implements the driver for this device (may be empty)device_name device name to use when registering the device sym_link1DOS/Win32 alias for the device (base name only, no DOS/ Win32 alias forthe device (base name only, no NT or Win32 prefixes like \??\ or \\.\)sym_link2 DOS/Win32 alias for the device (base name) id device ID (seeremarks below) Return CMST_NOT_FOUND no more devices Status: Example:See qry_open example. Remarks: Any of the string output fields in thebus (except device_name) may be empty: an empty class_name field meansthat the default name should be used an empty sym_link fields means thatthe symbolic link is not needed id is a value defined by the implementorand uniquely identifies this device. This value is valid as long as thepart that implements I_DEN is active and can be used to identify thedevice in calls to other terminals of the same part.

I_DIO, I_DIO_C—Device I/O Interface Overview

[5458] This is a device I/O interface. Supports bidirectional datatransfer and asynchronous operation. The interface also supports specialI/O control operation for the purposes of device control.

[5459] I_DIO_C is a conjugate interface used to receive notificationsfor completion; it has exactly one operation: complete.

[5460] This interface depends on data structures defined by the WindowsNT DDK.

List of Operations

[5461] Name Description Open Open a device object Cleanup Cancel allpending operations, prepare for close Close Cancel all pendingoperations, prepare for close Read Read data Write Write data ioctlExecute the IOCTL operation specified by ‘ioctl’. The definition ofIOCTL operations is outside the scope of this interface complete Reportcompletion of an operation

Operation Bus

[5462] BUS (B_DIO) // attributes flg32  attr; // attributes (DIO_A_xxx)uint32  buf_mapping; // DIO_MAP_xxx uint32  id; // device instance //identification _hdl  h; // handle (returned on open) // I/O operationdata void  *p; // pointer to data uint32  sz; // size of buffer pointedto by // p uint32  len; // length of data in *p LARGE_INTEGER ofs; //file offset (for block // devices) uint32  ioctl; // function code //asynchronous completion void  *irpp; // NT only: original I/O Request //Packet cmstat  cplt_s; // completion status (for // complete operationonly) END_BUS

Notes

[5463] 1. The term ‘object’ is used below to refer to the entity onwhich the I/O operations are performed. This can be a file, a device, apipe or any similar entity.

[5464] 2. This interface can be used for asynchronous operations ifthere is a back channel provided (e.g. the I_DIO connection isbi-directional). See the notes at the ‘complete’ operation description

[5465] 3. The DIO_A_PREVIEW is used for dispatching I_DIO operations tomultiple parts. If this attribute is set, the caller should interpretthe status as follows:

[5466] a. CMST_OK—the operation is acceptable, the part will process itsynchronously (i.e. will not return CMST_PENDING status).

[5467] b. CMST_SUBMIT—the operation is acceptable, the part claims theexclusive right to execute the operation. The operation may be processedsynchronously.

[5468] c. Other—the operation is not implemented. Note that the returnstatuses listed for the operations below assume that this flag is notset.

[5469] 4. The id field in the B_DIO bus is used to identify the instancethat should handle the operation. The use of this field is optional. Itis intended as storage for a part array index in one-to-manyconnections, but its use is not fixed by this interface.

[5470] open Description: Open a device object. In: id Device instanceidentification (see note #4 in the overview) attr Attributes, can be anyone of the following: DIO_A_PREVIEW “preview” operation DIO_A_ASYNC_CPLToperation may complete asynchronously p (WCHAR *) name of object to open(may be NULL) len Length of data pointed to by p (without terminating O)irpp (see complete operation) Out: h Handle to pass on subsequentoperations Return CMST_OK The operation was successful. Status:CMST_NOT_FOUND Specified object not found CMST_ACCESS_DENIED Objectalready open (if multiple opens are not supported) CMST_PENDING Seenotes for complete operation Example: B_DIO bus; // open device memset(&bus, O, sizeof (bus)); bus.p = L“MyDevice”; bus.len = sizeof(L“MyDevice”); s = out (dio, open, &bus); if (s != CMST_OK) . . . //device operations . . . // cancel any pending operations out (dio,cleanup, &bus); // close device out (dio, close, &bus); Remarks: Namedobject support and the naming conventions are outside the scope of thisinterface

[5471] cleanup Description: Cancel all pending operations, prepare forclose In: id Device instance identification (see note #4 in theoverview) attr Attributes, can be any one of the following:DIO_A_PREVIEW “preview” operation DIO_A_ASYNC_(—) operation CPLT maycomplete asynchro- nously h Handle from open irpp (see completeoperation) Out: void Return CMST_OK The operation was successful.Status: CMST_NOT_OPEN Object is not open. CMST_PENDING Operation isasynchronous, see notes for complete operation. Example: See example foropen. Remarks: No operations except close should be called after cleanup

[5472] close Description: Close a device object In: id Device instanceidentification (see note #4 in the overview) attr Attributes, can be anyone of the following: DIO_A_PREVIEW “preview” operation DIO_A ASYNC_(—)operation CPLT may complete asynchro- nously h Handle from open irpp(see complete operation) Out: void Return CMST_OK The operation wassuccessful. Status: CMST_NOT_OPEN Object is not open CMST_IOERR I/Oerror (nb: object is closed anyway) CMST_PENDING See notes for completeoperation Example: See example for open.

[5473] read Description: Read data In: id Device instance identification(see note #4 in the overview) attr Attributes, can be any one of thefollowing: DIO_A_PREVIEW “preview” operation DIO_A_ASYNC_CPLT operationmay complete asynchronously buf_mapping Buffering attributes, can be oneof the following: DIO_MAP_BUFFERED buffering is handled by caller, p isa valid virtual memory address DIO_MAP_DIRECT no buffering, p value issystem-dependent p Buffer pointer sz Size of buffer ofs File offset (forblock devices) h Handle from open irpp See complete operation Out: lenNumber of bytes read * p Data read Return CMST_OK The operation wassuccessful. Status: CMST_NOT_OPEN Object is not open CMST_IOERR I/Oerror CMST_PENDING See notes for complete operation Example: B_DIO bus;char buffer [256]; // open device memset (&bus, 0, sizeof (bus)); bus.p= L“MyDevice”; bus.len = sizeof (L“MyDevice”); s = out (dio, open,&bus); if (s != CMST_OK). . . // read from device bus.buf_mapping =DIO_BUF_DIRECT; bus.p = buffer; bus.sz = sizeof (buffer); bus.ofs =1000; bus.irpp = &irp; // NT request packet s = out (dio, read, &bus);if (s != CMST_OK). . . // cancel any pending operations out (dio,cleanup, &bus); // close device out (dio, close, &bus);

[5474] write Descrip- tion: Write data In: id Device instanceidentification (see note #4 in the overview) attr Attributes, can be anyone of the following: DIO_A_PREVIEW “preview” operation DIO_A_ASYNC_(—)operation may CPLT complete asynchronously buf_(—) Buffering attributes,can be one of the mapping following: DIO_MAP_(—) buffering is handledBUFFERED by caller, p is a valid virtual memory address DIO_MAP_(—) nobuffering, p value DIRECT is system-dependent p Pointer to data to bewritten sz Number of bytes to write ofs File offset (for block devices)h Handle from open irpp See complete operation Out: len Number of byteswritten Return CMST_OK The operation was successful. Status: CMST_(—)Object is not open NOT_(—) OPEN CMST_(—) I/O error IOERR CMST_(—) Mediafull (for block devices only) FULL CMST_(—) See notes for completeoperation PENDING Example: B_DIO bus; // open device memset (&bus, 0,sizeof (bus)); bus.p = L“MyDevice”; bus.len = sizeof (L“MyDevice”); s =out (dio, open, &bus); if (s != CMST_OK) . . . // write to devicebus.buf_mapping = DIO_BUF_DIRECT; bus.p = “MyString”; bus.sz = strlen(“MyString”) + 1; bus.ofs = 1000; bus.irpp = &irp; // NT request packets = out (dio, write, &bus); if (s != CMST_OK) . . . // cancel anypending operations out (dio, cleanup, &bus); // close device out (dio,close, &bus);

[5475] ioctl Execute the IOCTL operation specified by ioctl. Thedefinition of IOCTL operations is outside the scope of this Descrip-interface. For more information see the Windows NT DDK tion:documentation. In: id Device instance identification (see note #4 in theoverview) attr Attributes, can be any one of the following: DIO_A_(—)“preview” operation PREVIEW DIO_A_(—) operation may ASYNC_(—) completeCPLT asynchronously buf_(—) Buffering attributes, can be one of themapping following: DIO_MAP_(—) buffering is handled BUFFERED by caller,p is a valid virtual memory address DIO_MAP_(—) no buffering, p valueDIRECT is system-dependent p Pointer to input data and buffer for outputdata sz Size of output buffer len Length of input data ioctl IOCTLfunction code h Handle from open irpp See complete operation Out: lenLength of output data (never more than sz) *p Output data (depending onfunction code ioctl) Return CMST_OK The operation was successful.Status: CMST_NOT_(—) Object is not open OPEN CMST_(—) I/O error IOERRCMST_(—) See notes for complete operation PENDING CMST_NOT_(—) Thespecified IOCTL code is not SUPPORTED implemented Example: B_DIO bus;char buffer [256]; // open device memset (&bus, 0, sizeof (bus)); bus.p= L“MyDevice”; bus.len = sizeof (L“MyDevice”); s = out (dio, open,&bus); if (s != CMST_OK) . . . // write to device strcpy (buffer,“MyData”); bus.buf_mapping = DIO_BUF_DIRECT; bus.p = buffer; bus.sz =sizeof (buffer); bus.len = strlen (buffer) + 1; bus.ioctl =IOCTL_SMARTCARD_GET_ATTRIBUTE; bus.irpp = &irp; // NT request packet s =out (dio, write, &bus); if (s != CMST_OK) . . . // cancel any pendingoperations out (dio, cleanup, &bus); // close device out (dio, close,&bus);

[5476] complete Descrip- tion: Report completion of an operation In: hHandle to pass to subsequent operations (when completing open) lenLength of output data (if applicable, see I_DIO above) other See the‘out’ fields for each I_DIO operation irpp Must be as received with theoperation being completed cplt_s Completion status Out: void ReturnCMST_OK The operation was successful. Status: CMST_(—) irpp does notcorrespond to a valid INVALID pending operation Example: B_DIO bus; charbuffer [256]; // open device memset (&bus, 0, sizeof (bus)); bus.p =L“MyDevice”; bus.len = sizeof (L“MyDevice”); s = out (dio, open, &bus);if (s != CMST_OK) . . . // read from device asynchronously bus.attr =DIO_A_ASYNC_CPLT; bus.buf_mapping = DIO_BUF_DIRECT; bus.p = buffer;bus.sz = sizeof (buffer); bus.ofs = 1000; bus.irpp = &irp; // NT requestpacket s = out (dio, read, &bus); if (s != CMST_OK) . . . // . . .OPERATION (dio_c, complete, B_DIO) { // this is called when the readoperation completes return (CMST_OK); } END_OPERATION Remarks: Thisoperation is intended to be used in the client-to-server direction of abi-directional I_DIO/I_DIO_C terminal. If the server has to complete anyof the I_DIO operations described above asynchronously it should copythe bus and return CMST_PENDING. When the operation completes it fillsin the required ‘out’ fields in the bus and calls through the backchannel with the saved copy of the bus.

I_IRQ, I_IRQ_R—Interrupt Source Interface Overview

[5477] This is an interrupt source interface. It is used for enablingand disabling the event source and for receiving events when aninterrupt occurs.

List of Operations

[5478] Name Description enable Enable interrupt handling disable Disableinterrupt handling preview Preview interrupt event at device IRQL submitInterrupt event occurred (preview returned CMST_SUBMIT)

Operation Bus

[5479] BUS (B_IRQ) uint32  attr; // attributes _ctx  ctx ; // contextEND BUS

Notes

[5480] 1. The enable and disable operations must be invoked only atPASSIVE IRQL

[5481] 2. The preview operation is always sent at device IRQL (ininterrupt context). The operation implementation must be unguarded.

[5482] 3. The submit operation is always sent at DISPATCH IRQL.

[5483] enable Descrip- tion: Enable interrupt handling. In: void Out:void Return CMST_OK Interrupt handling is enabled. Status: CMST_NO_(—)The interrupt handling is already ACTION enabled. CMST_REFUSE Interruptsource cannot be enabled manually CMST_INVALID Failed to register ISRbecause of invalid properties. ST_BUSY The Interrupt is used exscluzivlyfrom sombody else Example: s = out (irq, enable, NULL); if (s != CMSTOK) . . . // enable interrupt generation // . . . // disable interruptgeneration s = out (irq, disable, NULL); if (s != CMST_OK) . . .Remarks: The enable operation must be invoked only at PASSIVE IRQL

[5484] disable Description: Disable interrupt handling In: void Out:void Return CMST_OK The operation was successful. Status: CMST_NO_(—)Interrupt event source is ACTION not enabled CMST_REFUSE Interrupt eventsource cannot be disabled manually Example: See example for enable.Remarks: The disable operation must be invoked only at PASSIVE IRQL.Upon successful return, the event source guarantees that it will notpreview or submit unless it is re-enabled.

[5485] preview Description: Preview an interrupt at device IRQL In: voidOut: ctx context for the subsequent submit operation Return CMST_(—)Interrupt handling completed, Status: OK no need for sending submitoperation CMST_(—) Interrupt event accepted. Send SUBMIT submitoperation at lower IRQL other error Interrupt not recognized, don'tstatus send submit. Example: None. Remarks: preview operation is alwayssent at device IRQL (in interrupt context) Note that if the interrupt islevel-sensitive (as opposed to edge-sensitive), this operation shouldclear at least one reason for the interrupt; if the the device does notdeassert the interrupt, the preview operation will be invoked again uponreturn.

[5486] submit Description: Process interrupt. In: ctx context returnedfrom preview Out: void Return CMST_OK Event accepted. Status: Example:None. Remarks: submit operation is always sent at DISPATCH IRQL

I_IOP—I/O Port Interface Overview

[5487] This is a generic I/O port interface.

List of Operations

[5488] Name Description in Read a byte (8-bits) from the I/O port mwRead a word (16-bits) from the I/O port indw Read a double word(32-bits) from the I/O port inbuf read sequence of bytes, words ordouble words from the I/O port out Output a byte (8-bits) to the I/Oport outw Output a word (16-bits) to the I/O port outdw Output a dword(32-bits) to the I/O port outbuf Output sequence of bytes, words ordouble words to the I/O port

Operation Bus

[5489] None

Notes

[5490] All operations can be invoked at any interrupt level.

[5491] in (CMIFCP (_iface), uint32 offs, byte *bp) Description: Read abyte (8-bits) from the I/O port In: offs base relative I/O port offsetbp pointer to a storage for 8-bit value Out: *bp 8-bit value read fromthe port Return CMST_OK operation finished successfully Status: Example:byte b; s = outX (io, in) ((_iface * const)top (io), 0, &b); if (s !=CMST_OK) . . . printf (“byte received 0x%02x\n”, b);

[5492] indw (CMIFCP (_iface), uint32 offs, word *wp) Description: Read aword (16-bits) from the I/O port In: offs base relative I/O port offsetwp pointer to a storage for 16-bit value Out: *wp 16-bit value read fromthe port Return CMST_OK operation finished successfully Status: Example:word w; s = outX (io, inw) ((_iface * const)top (io), 0, &w); if (s !=CMST_OK) . . . printf (“word received 0x%04x\n”, w);

[5493] indw (CMIFCP (_iface), uint32 offs, dword *dp) Description: Reada double word (32-bits) from the I/O port In: offs base relative I/Oport offset dp pointer to a storage for 32-bit value Out: *dp 32-bitvalue read from the port Return CMST_OK operation finished successfullyStatus: Example: word dw; s = outX (io, indw) ((_iface * const)top (io),0, &d); if (s != CMST_OK) . . . printf (“dword received 0x%081x\n”, d);

[5494] inbuf (CMIFCP (_iface),

[5495] uint32 offs,

[5496] uint32 unit_sz,

[5497] uint32 n_units,

[5498] void *bufp) Description: read sequence of bytes, words or doublewords from the I/O port In: offs base relative I/O port offset unit_szport size (in bytes) or size of the units. Must be 1 ,2 or 4 n_unitnumber of the units to be read from the port bufp output data buffer.The size of the buffer must be at least unit_sz * n_units (in bytes)Out: *bufp n_units read from the port Return CMST_OK operation finishedsuccessfully Status: Example: byte b; word w; dword dw[10]; s = outX(io, inbuf) ((_iface * const)top (io),          0,          sizeof(b),         1,          &b); if (s != CMST_OK) . . . printf (“byte received0x%02x\n”, b); s = outX (io, inbuf) ((_iface * const)top (io),         0,          sizeof(w),          1,          &w); if (s !=CMST_OK) . . . printf (“word received 0x%04x\n”, w); s = outX (io,inbuf) ((_iface * const)top (io),          0,          sizeof(dw[0]),         sizeof(dw)/sizeof(dw[0]),          &dw); if (s != CMST_OK) . .. printf (“1-st dword received = 0x%081x\n”, dw[0]);

[5499] out (CMIFCP (_iface), uint32 offs, byte b) Description: Output abyte (8-bits) to the I/O port In: offs base relative I/O port offset b8-bit output value Out: void Return CMST_OK operation finishedsuccessfully Status: Example: s = outX (io, out) ((_iface * const)top(io), 0, 0x12); if (s != CMST_OK) . . .

[5500] outw (CMIFCP (_iface), uint32 offs, word w) Description: Output aword (16-bits) to the I/O port In: offs base relative I/O port offset w16-bit output value Out: void Return CMST_OK operation finishedsuccessfully Status: Example: word w; s = outX (io, outw) ((_iface *const)top (io), 0, 0x1234); if (s != CMST_OK) . . .

[5501] otutdw (CMIFCP (_iface), uint32 offs, dword dw) Description:Output a dword (32-bits) to the I/O port In: offs base relative I/O portoffset dw 32-bit output value Out: void Return CMST_OK operationfinished successfully Status: Example: word dw; s = outX (io, outdw)((_iface * const) top (io),      0,      0x12345678); if (s != CMST_OK). . .

[5502] inbuf (CMIFCP (_iface),

[5503] uint32 offs,

[5504] uint32 unit_sz,

[5505] uint32 n_units,

[5506] void *bufp) Description: Output sequence of bytes, words ordouble words to the I/O port In: offs base relative I/O port offsetunit_sz port size (in bytes) or size of the units. Must be 1 ,2 or 4n_unit number of the units to be outputed to the port bufp data buffer.The length of the data is equal to unit_sz * n_units (in bytes) Out:void Return CMST_OK operation finished successfully Status: Example:byte b = 0x12; word w = 12345; dword dw[10] = {1, 2, 3, 4, 5, 6, 7, 8,9, 10}; s = outX (io, inbuf) ((_iface * const)top (io),          0,         sizeof(b),          1,          &b); if (s != CMST_OK) . . . s= outX (io, outbuf) ((_iface * const)top (io),          1234,         sizeof(w),          1,          &w); if (s != CMST_OK) . . . s= outX (io, inbuf) ((_iface * const)top (io),          333,         sizeof(dw[0]),          sizeof(dw)/sizeof(dw[0]),         &dw); if (s != CMST_OK) . . .

I_BYTEARR—Byte-Array Interface Overview

[5507] This interface provides access to a byte-array. It provides readand write operations for manipulation of the array. It also allowscontrol over the byte-array metrics (size).

[5508] The byte array may be fixed length or it may be dynamic—dependingon the implementation.

List of Operations

[5509] Name Description read read block of bytes starting at specifiedoffset write write block of bytes starting at specified offsetget_metrics get size of the array set_metrics set size of the array

Operation Bus

[5510] BUS (B_BYTEARR) void  p*  ; // buffer pointer uint32  offs ; //offset uint32  len ; //length of data in *p, [bytes] uint32  sz ; //size of buffer pointed to by p, // [bytes] flg32  attr ; // attributes,[BYTEARR_A_xxx] END_BUS

[5511] read Description: read block of bytes starting at specifiedoffset In: p buffer pointer sz size of buffer offs offset len how manybytes to read attr 0 to read < = len bytes, or BYTEARR_A_EXACT to readexactly len bytes Out: *p data len bytes actually read Return CMST_OKsuccessful Status: CMST_EOF cannot read requested len bytes (whenBYTEARR_A_EXACT) Example: B_BYTEARR bus; char buf [256]; cmstat s; //read 5 bytes starting at offset 10 bus.p = buf; bus.sz = sizeof (buf);bus.offs = 10; bus.len = 5; bus.attr = BYTEARR_A_EXACT; s = out (arr,read, &bus); if (s != CMST_OK) . . . Remarks: If BYTEARR_A_EXACT is notspecified, an attempt to read beyond the limits of supported spacereturns CMST_OK with len = = 0.

[5512] write Description: write block of bytes starting at specifiedoffset In: p pointer to data to be written offs offset len number ofbytes to write attr 0 to BYTEARR_A_GROW to grow automatically Out: voidReturn CMST_OK successful Status: CMST_OVERFLOW off + len is beyond thecurrent size of the array and BYTEARR_A_GROW was not specifiedCMST_NOT_(—) specified attribute is not SUPPORTED supported Example:B_BYTEARR bus; char buf [256]; cmstat s; // write 5 bytes starting atoffset 10 strcpy (buf, “12345”); bus.p = buf; bus.offs = 10; bus.len =5; bus.attr = 0; s = out (arr, write, &bus); if (s != CMST_OK) . . .

[5513] get_metrics Description: get size of the array In: void Out: lennumber of bytes available for reading from offset 0 sz number of bytesavailable for writing from offset 0 Return CMST_OK successful Status:Example: B_BYTEARR bus; cmstat   s; // get size of the array s = out(arr, get_metrics, &bus); if (s ! = CMST_OK) . . . // print size printf(“available for reading: %Id\n”, bus.len); printf (“available forwriting: %Id\n”, bus.sz );

[5514] set_metrics Description: set size of the array In: len number ofbytes to become available for reading from offset 0 sz number of bytesto become available for writing from offset 0 Out: void Return CMST_OKsuccessful Status: CMST_REFUSE if specified sz < specified lenCMST_ALLOC specified size cannot be reached (i.e., out of memory)CMST_NOT_SUP operation is not supported PORTED Example: B_BYTEARR bus;cmstat   s; // set size of the array bus.sz = 10; bus.len = 10; s = out(arr, set_metrics, &bus); if (s ! = CMST_OK) . . . Remarks: if len <current length, elements are removed if len > current length, elementsare filled with 0

I_USBCFG—USB Configuration Interface Overview

[5515] This interface is used to enumerate the set of available USBconfigurations on the current system. After enumeration, a configurationcan be set to the current configuration used by a USB driver. Theconfiguration list may be refreshed at any time.

List of Operations

[5516] Name Description refresh Refresh the list of availableconfigurations set Set a configuration or set to unconfigured state (id= NO_USBCFG) get Get currently selected configuration get_info Getinformation for specified configuration ID (‘id’ does not have to be thecurrent configuration) qry_open Open a query for enumeratingconfigurations qry_close Close a query for enumerating configurationsqry_first/qry_next Get first/next configuration reset Reset the USBdevice

Operation Bus

[5517] BUS( B_USBCFG ) // primary identification uint32  Id; //configuration ID // USB identification byte cfg_id; // configurationnumber byte ifc_id; // interface number byte alt_id; // alternatesetting number // configuration data word cfg_attr; // USBCFG_A_xxx wordcfg_pwr;  // 0-500 [ma] byte cfg_desc_idx;  //index of configuration //description string byte ifc_class; // (values are defined by the USB //standard) byte ifc_subclass;  // (values are defined by the USB //standard) byte ifc_protocol; // (values are defined by the USB //standard) uint32 n_endpts;  // number of entries in endpt[ ] // arrayENDPT endpt[MAX_ENDPTS]; // endpoint data END_BUS

[5518] refresh Description: Refresh the list of available configurationsIn: void Out: void Return CMST_OK configuration was read successfullyStatus: (other) failed to read configuration Remarks: Use of thisoperation is not required in order to use other operations of theI_USBCFG interface This operation may invalidate configuration IDsobtained with prior qry_first/qry_next operations

[5519] set Description: Set a configuration or set to unconfigured state(id = NO_USBCFG) In: id config ID from qry_first/qry_next or NO_USBCFGOut: void Return CMST_OK configuration was selected successfully Status:CMST_FAILED configuration was not selected Remarks: It is recommendedthat all activity on USB endpoints except endpoint 0 is suspended whencalling the ‘set’ operation. Implementation may not guarantee thatdevice state will be preserved if the operation fails. Upon successfulreturn from ‘set’ the device is configured and ready and all theendpoints are ready for data transfer.

[5520] get Description: Get currently selected configuration In: voidOut: id current configuration ID Return CMST_OK always (except fatalfailures) Status:

[5521] get_info Description: Get information for specified configurationID (‘id’ does not have to be the current configuration) In: id valuereturned by qry_first, qry_(—) next or get Out: (all fields - see notesat qry_first/qry_next) Return CMST_INVALID id is not valid (use onlyvalues Status: returned by qry_first/qry_next)

[5522] qry_open Description: Open a query for enumerating configurationsIn: void Out: void Return CMST_NO_ROO a query is already open Status: M

[5523] qry_close Description: Close a query for enumeratingconfigurations In: void Out: void Return CMST_NO_ACTI no query is openStatus: ON

[5524] qry_first/qry_next Description: Get first/next configuration In:id (for qry_next only) value from previous call to qry_first/qry_nextOut: (all B_USBCFG fields are set) Return CMST_NOT_FO there are no moreconfigurations Status: UND

[5525] reset Description: Reset the USB device; this operation executesthe reset sequence on the USB port and returns the device to itsunconfigured state. In: void Out: void Return CMST_ACCESS_ device isdisconnected Status: DENIED

Appendix 2—Events

[5526] This appendix describes preferred definition of events used byparts described herein.

[5527] EV_IDLE Overview: The EV_IDLE is a generic event used to signalthat idle processing can take place. Recipients of this event performprocessing that was postponed or desynchronized. Description: Signifiesthat a system is idle and that idle processing can take place. Event BusCMEVENT_HDR/CMEvent Definition: Return Depends on the consumer of theevent. Usually, the Status: following values are interpreted CMST_OKprocessing was performed; there is need for more idle-time processing,waiting for another idle event GMST_NO_AC there was nothing to do onthis event TION Example: /* my idle event definition - equivalent toCMEVENT_HDR */ EVENT (MY_IDLE_EVENT) // no event data END_EVENTMY_IDLE_EVENT idle_event; /* initialize idle event */ idle_event.sz =sizeof (idle_event); idle_event.attr = CMEVT_A_DFLT; idle_event.id =EV_IDLE; /* raise event through a I_DRAIN output */ out (drain, raise,&idle_event); Remarks: This event uses the CMEVENT_HDR/CMEvent directly;it does not have any event-specific data. There are no event-specificattributes defined for this event. This event is typically distributedsynchronously. See the overview of the I_DRAIN interface for adescription of the generic event attributes. See Also: I_DRAIN, DM_DWI,DM_IEV, CMEVENT_HDR, CMEvent

[5528] EV_REQ_ENABLE Overview: EV_REQ_ENABLE is a generic request toenable a particular procedure or processing. The nature of thisprocedure depends on the context and environment in which it is used.Description: Generic request to enable a particular procedure. Event BusCMEVENT_HDR/CMEvent Definition: Return Depends on the consumer of theevent Status: Example: EVENTX (MY_ENABLE_EVENT, EV_REQ_ENABLE,CMEVT_A_AUTO, CMEVT_UNGUARDED) char data[32]; END_EVENTX /* allocateenable event */ if (evt_alloc (MY_ENABLE_EVENT, &enable_eventp) !=CMST_OK) return; /* raise event through a I_DRAIN output */ memset(&enable_eventp−>data[0], 0×AA, sizeof (enable_eventp−>data)); out(drain, raise, enable_eventp); Remarks: This event does not have anyevent-specific data or attributes. If this event is distributedasynchronously, then the event bus must be self-owned. See the overviewof the I_DRAIN interface for a description of the generic eventattributes. See Also: I_DRAIN, DM_DWI, DM_IEV, CMEVENT_HDR/CMEvent

[5529] EV_REQ_DISABLE Overview: EV_REQ_DISABLE is a generic request todisable a particular procedure or processing. The nature of thisprocedure depends on the context and environment in which it is used.Description: Generic request to disable a particular procedure. EventBus CMEVENT_HDR/CMEvent Definition: Return Depends on the consumer ofthe event Status: Example: EVENTX (MY_DISABLE_EVENT, EV_REQ_DISABLE,CMEVT_A_AUTO, CMEVT_UNGUARDED) char data[32]; END_EVENTX /* allocatedisable event */ if (evt_alloc (MY DISABLE_EVENT, &disable_eventp) !=CMST_OK) return; /* raise event through a I_DRAIN output */ memset(&disable_eventp−>data[0], 0×AA, sizeof (disable_eventp−>data)); /*raise event through a I_DRAIN output */ out (drain, raise, disableeventp); Remarks: This event does not have any event-specific data orattributes. If this event is asynchronous, then the event bus must beself-owned. See the overview of the I_DRAIN interface for a descriptionof the generic event attributes. See Also: I_DRAIN, DM_DWI, DM_IEV,CMEVENT_HDR, CMEvent

[5530] EV_REP_NFY_DATA_CHANGE Overview: This event is generated when arepository data item or a subtree changes. The change may be that avalue has been modified, added or deleted. The originator of the eventmay use the event with an indication that a whole subtree has beenchanged in order to avoid notifying for each item separately.Description: Notification that a repository data item has been modified,added, or deleted Event Bus EVENTX (EV_REP, EV_REP_NFY_DATA_CHANGE,Definition: CMEVT_A_AUTO, CMEVT_UNGUARDED) // repository event specificdata char path[I_ITEM_MAX_PATH]; // full path to affected // entitybool32 is_subtree // TRUE if the whole // subtree is affected END_EVENTXData: path Full data path to affected data item or subtree rootis_subtree TRUE the if whole subtree below the path specified by pathhas changed. If this member is FALSE, only the item at the specifiedpath has changed. Return Since this is a notification of an action thathas already Status: occurred and does not depend on processing by therecipient, originators of this event can safely ignore the returnedstatus. Example: OPERATION (nfy, raise, EV_REP) { /* valchk */ if (bp ==NULL) return (CMST_NULL_PTR); if (bp−>id != EV REP_NFY_DATA_CHANGE) { /*free bus if self-owned */ if (bp−>attr & CMEVT_A_SELF_OWNED) evt_free(bp); return (CMST_OK); } /* find out which path changed */ if (stricmp(bp−>path, “customers[1].name”) == 0) printf (“customer #1 name haschanged.\n”); if (stricmp (bp−>path, “customers[2].name”) == 0) printf(“customer #2 name has changed.\n”); /* find out if the whole subtreewas affected */ if (bp−>is_subtree) printf (“The whole subtree wasaffected\n”); /* free bus if self-owned */ if (bp−>attr &CMEVT_A_SELF_OWNED) evt_free (bp); return (CMST_OK); } END_OPERATIONRemarks: The EV_REP_NFY_DATA_CHANGE event is generated by DM_REP when arepository data item changes (added, changed, deleted). There are noevent-specific attributes defined for this event. The event bus containsall the information about the affected entity. It contains the affecteddata path and whether or not the whole subtree under that path wasaffected. If this event is distributed asynchronously, then the eventbus must be self-owned. Note that, since the event contains the storagefor the path and not only a pointer to it, the event is self-containedand can be distributed asynchronously. See the overview of the I_DRAINinterface for a description of the generic event attributes. See Also:I_DRAIN, DM_REP

[5531] EV_RESET Overview: This event is a generic request for reset.Recipients of this event should immediately reset their state and getready to operate again as if they were just activated. Description:Reset the internal state of a part. Event Bus CMEVENT_HDR/CMEventDefinition: Return Depends on the consumer of the event Status: Remarks:This event does not have any event-specific data or attributes. If thisevent is asynchronous, then the event bus must be self-owned. See theoverview of the I_DRAIN interface for a description of the generic eventattributes. See Also: I_DRAIN, DM_DWI, CMEVENT_HOR, CMEvent

[5532] EV_MESSAGE Overview: This event contains a message received or tobe transmitted through some communication channel. The event containsthe actual data and its length. The event also contains an indication ofwhether the data is corrupted or not. Description: Send a string ofbytes Event Bus EVENTX (B_EV_MSG, EV_NULL, Definition: CMEVT_A_SYNCCMEVT_A_SELF_OWNED CMEVT_A_SELF_CONTAINED, CMEVT_UNGUARDED) uint len ;// length of the data char data[1]; // variable size data END_EVENTData: attr MSG_A_NONE no attrubutes MSG_A_BAD_DAT message consists A ofbad data len length of message data data beginning of message dataReturn CMST_OK event processed successfully Status: Remarks: Thismessage must be sent with the EV_A_SYNC attribute set.

[5533] EV_EXCEPTION Overview: This event signifies that an exception hasoccurred which requires special processing. More than one recipient canprocess this event. Description: Raise exception. Event Bus EVENTX(B_EV_EXC, EV_EXCEPTION, Definition: CMEVT_A_SYNC |CMEVT_A_SELF_CONTAINED, CMEVT_UNGUARDED) // exception identificationdword exc_Id ; // exception ID byte exc_class ; // type of exceptionbyte exc_severity ; // severity, [CMERR_XXX] // source identificationcmoid oid ; // oid of original issuer cmoid oid2 ; // current aid charpath[48]; // path along the assembly // hierarchy (dot-separated //names as in the SUBORDINATES // tables) char class_name[24]; // classname char file_name[24]; // file name dword line ; // line number infile // context char term_name[16]; // terminal name char oper_name[16];// operation name cmstat cm_stat ; // GlassMagic status (optional) dwordos_stat // OS-dependent status _ctx ctx1 ; // optional context (see //EXC_A_xxx) _ctx ctx2 ; // optional context (see // EXC_A_xxx) //insertschar format[16]; // defines format of data[ ] byte data[128]; // packedinsert data, as // specified by the // format ‘field’ Data: attrAttributes, can be any one of the following: EXC_A_GTX1 _IRP ctx1 is apointer to IRP EXC_A_CTX2_IO ctx2 is an I/O M manager object exc_idexception ID exc_class type of exception, reserved exc_severityseverity, [CMERR_XXX] oid old of original issuer oid2 current oid - usedto trace assembly path path path along the assembly hierarchy (dot-separated names as in the SUBORDINATES tables) class_name ClassMagicclass name file_name source file name line line number in file term_nameterminal name oper_name operation name cm_stat ClassMagic status(CMST_xxx) os_stat system status (NT status, Win32 error, etc.) ctx1optional context (see EXC_A_xxx) ctx2 optional context (see EXC_A_xxx)format defines format of the ‘data’ field, one char defines one datafield as follows: b, w, d - byte, word, dword (to be printed in hex) i,u - signed integer, unsigned integer (dword, decimal) c - byte (to beprinted as a character) s - asciiz string S - unicodez string 1 . . .9 - 1 to 9 dwords of binary data data packed insert data, as specifiedby format ‘field’ Return CMST_OK The event was processed Status:successfully Remarks: All fields except exc_xxx, class_name, file_nameand line are optional, set them to binary Os if not used Useguidelines: 1) original issuer should: initialize all mandatory fieldsset ‘oid’ and ‘oid2’to the same value (sp−>self) zero-mit the followingfields, they are for use only by exception processing parts: path 2) allunused fields should be zero-initialized

[5534] EV_LFC_REQ_START Overview: This life cycle event is used tosignal that normal operation can begin. Recipients may commenceoperation immediately (the usual practice) and return after they havestarted. Recipient can postpone the starting for asynchronous completionand raise EV_LFC_NFY_START_CPLT event when ready. Description: Startnormal operation Event Bus EVENT (B_EV_LFC) Definition: cmstat cplt_s;// completion status (asynchronous completion) END_EVENT Data: attrstandard event attributes, optionally LFC_A_ASYNC_CPLT Return CMST_OKstarted OK Status: CMST_PENDING postponed for asynchronous completion(allowed if LFC_A_ASYNC_CPLT is specified; otherwise treated as failure)any other start failed Remarks: If LFG_A_ASYNC_CPLT is specified, therecipient may return CMST_PENDING and complete the start later bysending EV_LFC_NFY_START_CPLT.

[5535] EV_LFC_REQ_STOP Overview: This life cycle event is used to signalthat normal operation should end. Typically recipients initiate thestopping procedure immediately and return after this procedure iscomplete. Recipient can postpone the starting for asynchronouscompletion and raise EV_LFC_NFY_STOP_CPLT event when ready. Description:Stop normal operation Event Bus EVENT (B_EV_LEG) Definition: cmstatcplt_s; // completion status (asynchronous completion) END_EVENT Data:attr standard event attributes, optionally LEG_A_ASYNC_CPLT ReturnCMST_OK Stop completed Status: CMST_PENDING postponed for asynchronouscompletion (allowed if LEG_A_ASYNC_CPLT is specified; otherwise treatedas failure) any other stop failed Remarks: If LEG_A_ASYNC_GPLT isspecified, the recipient may return CMST_PENDING and complete the stoplater by sending EV_LFG_NFY_STOP_CPLT. In case stop fails, the recipientshould still clean up as much as possible -- in many cases, stopfailures are ignored (e.g., NT kernel mode drivers are unloaded, even ifthey fail to stop properly).

[5536] EV_LFC_NFY_START_CPLT Overview: This event indicates that thestarting procedure has completed. The event is used when an asynchronouscompletion is needed and complements EV_LFC_REQ_START event.Description: Start has completed Event Bus EVENT (B_EV_LFC) Definition: cmstat cplt_s; // completion status      // (asynchronous completion)END_EVENT Data: cplt_s     completion status Return The return status isignored Status: Remarks: Start has completed successfully if cplt_s isCMST_OK, failed otherwise this event is sent in response toEV_LFC_REQ_START on which CMST_PENDING was returned; it goes in theopposite direction of EV_LFC_REQ_START

[5537] EV_LFC_NFY_STOP_CPLT Overview: This event indicates that thestopping procedure has completed. The event is used when an asynchronouscompletion is needed and complements EV_LFC_REQ_STOP event. Description:Stop has completed Event Bus EVENT (B_EV_LFC) Definition:  cmstatcplt_s; // completion status      // (asynchronous completion) END_EVENTData: cplt_s     completion status Return The return status is ignoredStatus: Remarks: Stop has completed successfully if cplt_s is CMST_OK,failed otherwise this event is sent in response to EV_LFC_REQ_STOP onwhich CMST_PENDING was returned; it goes in the opposite direction ofEV_LFC_REQ_STOP In case stop fails, the sender should still clean up asmuch as possible -- in many cases, stop failures are ignored (e.g., afile handle becomes invalid even if close failed).

[5538] EV_PRP_REQ

Overview

[5539] This event is used to request a part to execute a propertyoperation. All of the standard DriverMagic property operations aresupported and are specified in the event as an op-code. The input andoutput parameters for each operation is dependent upon the op-code.

[5540] Each property operation is described below. Event Bus  EVENTX(B_EV_PRP, EV_PRP_REQ, CMEVT_A_(—) DFLT, CMEVT_UNGUARDED)  uint32cplt_s ; // completion status, [CMST_xxx]  _ctx context ; // IOCTLcontext  uint32  opcode ; // property operation code,     //[PROP_OP_xxx]  _hdl qryh ; // query handle  char  name[64] ; //property name  uint16 type ; // property type, [CMPRP_T_XXX] flg32 prp_attr ; // property attributes,   [CMPRP_A_XXX] flg32 attr_mask; // property attribute mask,      // [CMPRP_A_XXX] uint32 size ; // size of data in bytes  uint32 len ; // length of datain bytes  byte data[1] ; // buffer for property value END_EVENTX

[5541] PROP_OP_GET Description: Get a property In: context 32-bitcontext opcode operation id, [PROP_OP_GET] name null-terminated propertyname type type of the property to retrieve or CMPRP_T_NONE for any sizesize of data, [bytes] data[] buffer to receive property value Out:cplt_s completion status, [CMST_xxx] len length of data returned indata[] data property value Return CMST_OK success Status: CMST_REFUSEthe data type does not match the expected type CMST_NOT_ unknownproperty FOUND CMST_OVERFLOW the buffer is too small to hold theproperty value

[5542] PROP_OP_SET Description: Set a property In: context 32-bitcontext opcode operation id, [PROP_OP_SET] name null-terminated propertyname type property type, [CMPRP_T_XXX] len length [in bytes] of datastored data[] in data property value Out: cplt_s completion status,[CMST_xxx] Return CMST_OK success Status: CMST_NOT_(—) unknown propertyFOUND CMST_OVERFLOW the property value is too large CMST_REFUSE theproperty type is incorrect or the property cannot be changed while thepart is in an active state CMST_OUT_OF_(—) the property value is notwithin the RANGE range of allowed values for this property CMST_BAD_(—)there has been an attempt to set a ACCESS read-only property

[5543] PROP_OP_CHK Description: Check if a property can be set to thespecified value In: context 32-bit context opcode operation id,[PROP_OP_CHK] name null-terminated property name type type of theproperty value to check len size in bytes of property value data[]buffer containing property value Out: cplt_s completion status,[CMST_xxx] Return CMST_OK successful Status: CMST_NOT_(—) the propertycould not be found or FOUND the id is invalid CMST_OVERFLOW the propertyvalue is too large CMST_REFUSE the property type is incorrect or theproperty cannot be changed while the part is in an active stateCMST_OUT_OF_(—) the property value is not within the RANGE range ofallowed values for this property CMST_BAD_(—) there has been an attemptto set a ACCESS read-only property

[5544] PROP_OP_GET_INFO Description: Retrieve the type and attributes ofthe specified property In: context 32-bit context opcode operation id,[PROP_OP_GET_INFO] name null-terminated property name Out: cplt_scompletion status, [CMST_xxx] type type of property, [CMPRP_T_XXX]prp_attr property attributes, [CMPRP_A_XXX] Return CMST_OK successfulStatus: CMST_NOT_(—) the property could not be found FOUND

[5545] PROP_OP_ORY_OPEN Description: Open a query to enumerateproperties on a part based upon the specified attribute mask and valuesor CMPRP_A_NONE to enumerate all properties In: context 32-bit contextopcode operation id, [PROP_OP_QRY_OPEN] name query string (must be “*”)prp_attr attribute values of properties to include attr_mask attributemask of properties to include Out: cplt_s completion status, [CMST_xxx]qryh query handle Return CMST_OK successful Status: CMST_NOT_(—) thespecified part does not support SUPPORTED property enumeration or doesnot support nested or concurrent property enumeration Remarks: To filterby atrributes, specifiy the set of attributes in attr_mask and theirdesired values in prp_attr. During the enumeration, a bit-wise AND isperformed between the actual attributes of each property and the valueof attr_mask; the result is then compared to prp_attr. If there is anexact match, the property will be enumerated. To enumerate allproperties of a part, specifiy the query string as “*”, and attr_maskand prp_attr as 0. The attribute mask can be one or more of thefollowing: CMPRP_A_NONE not specified CMPRP_A_PERSIST persistentproperty CMPRP_A_ACTIVETIME property can be modified while activeCMPRP_A_MANDATORY property must be set before activation CMPRP_A_RDONLYread-only property CMPRP_A_UPCASE force uppercase CMPRP_A_ARRAY propertyis an array

[5546] PROP_OP_QRY_CLOSE Description: Close a query In: context 32-bitcontext opcode operation id, [PROP_OP_QRY_CLOSE] qryh query handle Out:cplt_s completion status, [CMST_xxx] Return CMST_OK successful Status:CMST_NOT query handle was not found or is FOUND invalid CMST_BUSY theobject can not be entered from this execution context at this time

[5547] PROP_OP_ORY_FIRST Description: Retrieve the first property in aquery In: context 32-bit context opcode operation id,[PROP_OP_QRY_FIRST] qryh query handle returned on PROP_OP_QRY_OPEN sizesize in bytes of data data[] storage for the returned property name Out:cplt_s completion status, [CMST_xxx] data property name if size is not 0len length of data (including null terminator) Return CMST_OK successfulStatus: CMST_NOT_(—) no properties found matching current FOUND queryCMST_(—) buffer is too small for property name OVERFLOW

[5548] PROP_OP_QRY_NEXT Description: Retrieve the next property in aquery In: context 32-bit context opcode operation id, [PROP_OP_QRY_NEXT]qryh query handle returned on PROP_OP_QRY_OPEN size size in bytes ofdata data[] storage for the returned property name Out: cplt_scompletion status, [CMST_xxx] data property name if size is not 0 lenlength of value (including null terminator) Return CMST_OK successfulStatus: CMST_NOT_(—) there are no more properties that FOUND match thequery criteria CMST_OVERFLOW buffer is too small for property name

[5549] PROP_OP_QRY_CURR Description: Retrieve the current property in aquery In: context 32-bit context opcode operation id, [PROP_OP_QRY_CURR]qryh query handle returned on PROP_OP_QRY_OPEN size size in bytes ofdata data[] storage for the returned property name Out: cplt_scompletion status, [CMST_xxx] data property name if size is not 0 lenlength of value (including null terminator) Return CMST_OK successfulStatus: CMST_NOT_(—) no current property (e.g. after FOUND a call toPROP_OP_(—) QRY_OPEN) CMST_OVERFLOW buffer is too small for propertyname

[5550] EV_PULSE Overview: EV_PULSE is a generic event that gives arecipient an opportunity to execute in the sender's execution context.Description: Gives recipient an opportunity to execute in sender'sexecution context. Event Bus uses CMEVENT_HDR/CMEvent Definition: ReturnCMST_OK recipient executed OK Status: CMST_NO_ACTION recipient didn'thave any action to be performed Remarks: This event is typicallydistributed only synchronously. A sender of this event may re-send theevent until CMST_NO_ACTION is returned, allowing the receipient tocomplete all pending actions'.

[5551] This chapter provides details on the events used by WDK.

[5552] The first three events are extensions to the standard life-cycleevent set provided by DriverMagic. These operate on the same bus andtheir event IDs are binary compatible with the standard life-cycle eventIDs.

[5553] The third event EV_REQ_IRP is a request to process IRP. Thisevent is the fundamental carrier of request packets entering the driver.The ownership of the IRP travels with the event.

[5554] The next seven events are used to request operations on devicedrivers. Each event corresponds to an operation on the I_DIO interface.These events are mainly used for communication with other devicedrivers.

[5555] The last three events are used for keyboard interaction. Only theDM_A2K part uses these events.

[5556] All requests can be completed synchronously or asynchronously(default). Some parts may refuse operation if asynchronous completion isnot allowed. If this creates a problem, use DM_RSB part from theAdvanced Part Library. For more information, consult the DM_RSB datasheet in the Advanced Part Library documentation.

[5557] In case of asynchronous completion, the same event is sent backwith CMEVT_A_COMPLETED attribute set, to indicate that the processing ofthe event is complete.

[5558] EV_LFC_REQ_DEV_PAUSE Overview: This is a request to pause theoperation with the device. Recipients of this event may process itsynchronously or asynchronously. In the later case they have to issuethe same event with CMEVT_A_COMPLETED attribute set. Description:Request to pause the device Event Bus EVENT (B_EV_LFC) Definition: cmstat cplt_s; // completion status       // (asynchronous completion)END_EVENT Data: cplt_s Completion status attr CMEVT_A_ASYNC_CPLT- ifasynchronous completion is allowed CMEVT_A_(—) COMPLETED-if the event isa completion event. Return CMST_PENDING callee assumes responsibility toStatus: complete the request later (either directly or by sending backthe same event with CMEVT_A_(—) COMPLETED set) Remarks This event isdefined in e_lfc_ex.h.

[5559] EV_LFC_REQ_DEV_RESUME Overview: This is a request to resume theoperation with the device. Recipients of this event may process itsynchronously or asynchronously. In the later case they have to issuethe same event with CMEVT_A_COMPLETED attribute set. Description:Request to resume the device Event Bus EVENT (B_EV_LFC) Definition: cmstat cplt_s; // completion status       // (asynchronous completion)END_EVENT Data: cplt_s Completion status attr CMEVT_A_ASYNC_CPLT- ifasynchronous completion is allowed CMEVT_A_(—) COMPLETED-if the event isa completion event. Return CMST_PENDING callee assumes responsibility toStatus: complete the request later (either directly or by sending backthe same event with CMEVT_A_(—) COMPLETED set) Remarks This event isdefined in e_lfc_ex.h.

[5560] EV_LFC_NFY_DEV_REMOVED Overview: This is a post-notification thatthe device has been removed. Recipients of this event may process itsynchronously only. In no event recipients of this event can access thehardware device-at the time this event is sent, the hardware device mayhave been unplugged. Description: Notification that the device has beenremoved. Event Bus EVENT (B_EV_LFC) Definition:  cmstat cplt_s; //completion status       // (asynchronous completion) END_EVENT RemarksThis event is defined in e_lfc_ex.h. This event is a notification andcannot be completed asynchronously.

[5561] EV_REQ_IRP Overview: This event indicates that an IRP (I/Orequest packet) needs processing. Recipients of this event may processit synchronously or asynchronously. In the later case they have to issuethe same event with CMEVT_A_COMPLETED attribute set. Description:Process the I/O request Event Bus EVENT (B_EV_IRP, EV_REQ_IRP,Definition:  CMEVT_A_NONE, CMEVT_UNGUARDED)  dword devid ; // instanceID  void *irpp ; // pointer to IRP  cmstat cplt_s; // completion statusEND_EVENTX Data: devid ID of the instance that should process therequest irpp pointer to IRP (NT I/O reqeust packet) Return CMST_PENDINGcallee assumes responsibility to Status: complete the request later(either directly or by sending back an EV_REQ_IRP event withCMEVT_A_COMPLETED set) Remarks This value of devid isimplementation-specific. This event is defined in e_irp.h.

[5562] EV_KBD_EVENT Overview: This event is sent when keyboard data ispresent either from the user pressing a key or another part emulatingkeystrokes. Description: Notifies that the specified keyboard event hasoccurred. Event Bus EVENTX (B_EV_KBD, EV_KBD_EVENT, Definition:  CMEVT_A_SELF_CONTAINED | CMEVT_A_(—)   SYNC, CMEVT_UNGUARDED) uint16data;  // keyboard event data (raw data         // or shift state)uint16 flags;  // KBD_F_xxx uint32 time_delta; // time since theprevious event         // (msec) uint32 dev_data[4]; //originator-specific data, do         // not modify END_EVENTX Data: attrevent attributes- CMEVT_A_CONST and/or KBD_A_DEVICE_KBD (indicates eventis generated by actual data device) keyboard data (device-specific)flags keyboard flags, may be one or more of the following: KBD_R_(—)Indicates that the BREAK event is a “key release” event KBD_F_E0 Oxe0prefix was sent with key (AT-key- board specific and may be ignored ifnot needed) KBD_F_E1 Oxe1 prefix was sent with key (AT-key- boardspecific and may be ignored if not needed) time_delta time [in msec]since the previous event. If there was no previous event or the timesince the previous event exceeds the size of a 32- bit integer,time_delta is set to 0xffffffff. This field is optional and not allevent sources have to support it. dev_data[] originator context data.must be preserved by recipients of this event. Event filters thatprocess EV_KBD_EVENTs should pass this data on unchanged. Return CMST_OKevent was processed successfully Status: CMST_NOT_(—) the recipient doesnot support new SUPPORTED event insertion (may be returned ifKBD_A_DEVICE_EVT attribute is not set) (other) other (valchk/fatal)errors may be returned if receiver cannot process event Remarks: if a“fake” keyboard event is initiated by a non-keyboard part, it should setthe dev_data[] fields to 0. The “fake” event is recognized by theKBD_A_DEVICE_EVT flag in the attr field-it is 0 for such events and 1for actual device events. Support for “fake” events may be limited byoperating system (or other) restrictions.

[5563] EV_KBD_STATE_NFY Overview: This event is sent when the state ofthe shift, control, alt or lock (scroll, num and caps) keys of thekeyboard has changed. Description: Notifies that the keyboards shiftkeys are in the specified state. Event Bus EVENTX (B_EV_KBD,EV_KBD_EVENT, Definition:  CMEVT_A_SELF_CONTAINED | CMEVT_A_(—)  SYNC,CMEVT_UNGUARDED) uint16 data;   // keyboard event data (raw data       // or shift state) uint16 flags;   // KBD_F_xxx uint32time_delta; // time since the previous event         // (msec) uint32dev_data[4]; // originator-specific data, do         // not modifyEND_EVENTX Data: attr event attributes- CMEVT_A_CONST and/orKBD_A_DEVICE_KBD (indicates event is generated by actual device) databit flag specifying current shift and lock state, may be one or more ofthe following: KBD_SF_(—) Right shift pressed RSHIFT KBD_SF_(—) Leftshift pressed LSHIFT KBD_SF_(—) Control pressed CTRL KBD_SF_(—) Altpressed ALT KBD_SF_(—) Scroll lock on SCROLL KBD_SF_(—) Num lock on NUMKBD_SF_(—) Caps lock on CAPS flags bit mask specifying which of the bitsin data are valid (if a bits is ‘0’ in flags, the corresponding bit indata should be ignored)

[5564] EV_KBD_GET_STATE Overview: This event is sent to find out thecurrent state of the shift, control, alt and lock state (scroll, num andcaps) of the keyboard. Description: Request current shift and lockstate. Event Bus EVENTX (B_EV_KBD, EV_KBD_EVENT, Definition: CMEVT_A_SELF_CONTAINED | CMEVT_A_(—)  SYNC, CMEVT_UNGUARDED) uint16data;   // keyboard event data (raw data        // or shift state)uint16 flags;   // KBD_F_xxx uint32 time_delta; // time since theprevious event         // (msec) uint32 dev_data[4]; //originator-specific data, do         // not modify END_EVENTX Data: databit flag specifying current shift and lock state, may be one or more ofthe following: KBD_SF_(—) Right shift pressed RSHIFT KBD_SF_(—) Leftshift pressed LSHIFT KBD_SF_(—) Control pressed CTRL KBD_SF_(—) Altpressed ALT KBD_SF_(—) Scroll lock on SCROLL KBD_SF_(—) Num lock on NUMKBD_SF_(—) Caps lock on CAPS flags bit mask specifying which of the bitsin data are valid (if a bits is ‘0’ in flags, the corresponding bit indata should be ignored) Return CMST_OK event was processed successfullyStatus: CMST_NOT_(—) the recipient does not support the SUPPORTEDrequest (other) other (valchk/fatal) errors may be returned

Device I/O Events—Notes

[5565] The following notes apply to all the device 110 events definedbelow:

[5566] 1. The term ‘object’ is used below to refer to the entity onwhich the I/O operations are performed. This can be a file, a device, apipe or any similar entity.

[5567] 2. The dev_id field in the B_EV_DIO bus can be used to identifythe instance that should handle the operation. The use of this field isoptional. It is intended as storage for a part or connection ID inone-to-many connections. Its use is not explicitly defined here.

[5568] 3. The dev_h field in the B_EV_DIO bus is usually a handle of adevice or of a file opened on the device.

[5569] 4. All EV_DIO_RQ_xxx requests can be completed asynchronously,provided that the originator has set the CMEVT_A_A SYNC_CPLT attribute.To complete a request asynchronously, recipient should perform thefollowing actions:

[5570] a) save the event bus pointer

[5571] b) return CMST_PENDING

[5572] c) if necessary, use the event bus during processing (the eventbus is exclusively available to the part that is processing the request)

[5573] d) when request is completed, use the saved bus pointer and

[5574] fill in the completion status (cplt_s)

[5575] fill in all fields specified as ‘out’ for the request

[5576] set the CMEVT_A_COMPLETED attribute (all other fields, esp. ctx,must be preserved)

[5577] send the completion event (typically out the terminal throughwhich the request was received).

[5578] If the CMEVT_A_A_SYNC_CPLT attribute is not set, the request mustbe completed synchronously.

[5579] 5. The ctx field is used by the request originator to store itscontext. This value is not to be interpreted or modified by any partthat processes the event, unless the originator has set the DIO_A_NT_IRPattribute to indicate that ctx contains a pointer to a NT driver IRP(I/O request packet) associated with the event. The DIO_A_NT_IRPattribute shall be clear if ctx does not contain pointer to a valid IRP.

[5580] 6. (Note specific to Windows NT kernel mode and WDM environments)If ctx contains pointer to NT driver IRP, the rules for intermediatedrivers apply to the processors of the EVD_DIO_RQ_xxx request: they canuse the next and lower stack locations. In no case the IRP should becompleted. If the IRP's next stack location is used to call alower-level driver in the device's stack, the caller must set acompletion routine and prevent full completion of the IRP—the requestshould be completed according to note #4 above.

[5581] 7. The DIO_A_UNICODE attribute can be set on EV_DIO_RQ_OPEN toindicate that the object name pointed by buf_p is a unicode string. Notethat in Windows NT kernel mode and WDM environments, the string may notbe zero-terminated; the length is always correctly specified in buf_len(in bytes, excluding any zero terminator). If the DIO_A_UNICODEattribute is not set, buf_p on EV_DIO_RQ_OPEN is either NULL or pointsto a valid 0-terminated ASCII string. If buf p is NULL, DIO_A_UNICODEshould not be set.

[5582] EV_DIO_RQ_OPEN Overview: This event is used to open a specificdevice driver or file. The entity being opened is identified by a pathspecified with the event. The format of the path is defined by theoperating system. Description: Open a device or file object. Event BusEVENT (B_EV_DIO) Definition: cmstat cplt_S ; // completion status //(asynchronous completion) dword ctx ; // originator's context value //(may be IRP) uint32 dev_id ; // device instance // identification _hdldev_h ; // device handle uint32 func ; // function code (for IOCTL)LARGE_INTEGER offs ; // file offset (for block // devices) void *buf_p ;// pointer to data uint32 buf_sz ; // size of buffer pointed to // by p,[bytes] uint32 buf_len ; // length of data in *buf_p. // [bytes]END_EVENT Data: dev_id device instance identification (see note #2above) buf_p name of object to open (may be NULL) (see note #7) buf_lenlength of data pointed to by ‘buf_p’ (without the terminating 0),[bytes] buf_h device handle to pass on subsequent operations (out)Return CMST_NOT_FOU specified object not found Status: ND CMST_ACCESS_object already open (if multiple opens DENIED are not supported)Remarks: Named object support and the naming conventions are outside thescope of this interface. If DIO_A_UNICODE is specified, buf_p is to beinterpreted as WCHAR * and the string may not be 0-terminated.

[5583] EV_DIO_RQ_CLEANUP Overview: This request is sent to cancel allpending operations on a specific device driver and to prepare it forclosing. Description: Cancel all pending operations, prepare for close.Event Bus EVENT (B_EV_DIO) Definition: cmstat cplt_s ; // completionstatus // (asynchronous completion) dword ctx ; // originator's contextvalue // (may be IRP) uint32 dev_id // device instance // identification_hdl dev_h ; // device handle uint32 func ; // function code (for IOGTL)LARGE_INTEGER offs ; // file offset (for block // devices) void *buf_p ;// pointer to data uint32 buf_sz ; // size of buffer pointed to // by p,[bytes] uint32 buf_len ; // length of data in *buf_p. // [bytes]END_EVENT Data: dev_id device instance identification (see note #2above) dev_h device handle from ‘open’ Return CMST_NOT_OPE object is notopen Status: N Remarks: No operations except ‘close’ should be calledafter ‘cleanup’.

[5584] EV_DIO_RQ_CLOSE Overview: This request is sent to close aspecific deivce driver or file. Description: Close a device object.Event Bus EVENT (B_EV_DIO) Definition: cmstat cplt_s ; // completionstatus // (asynchronous completion) dword ctx ; // originator's contextvalue // (may be IRP) uint32 dev_id ; // device instance //identification _hdl dev_h ; // device handle uint32 func ; // functioncode (for IOCTL) LARGE_INTEGER offs ; // file offset (for block //devices) void *buf_p ; // pointer to data uint32 buf_sz ; // size ofbuffer pointed to // by p, [bytes] uint32 buf_len ; // length of data in*buf_p. // [bytes] END_EVENT Data: dev_id device instance identification(see note #2 above) dev_h device handle from ‘open’ Return CMST_NOT_OPEobject is not open Status: N CMST_IOERR I/O error (object is closedanyway)

[5585] EV_DIO_RQ_READ Overview: This request is sent to read data from aspecific device driver or file. Description: Read data from device.Event Bus EVENT (B_EV_DIO) Definition: cmstat cplt_s ; // completionstatus // (asynchronous completion) dword ctx ; // originator's contextvalue // (may be IRP) uint32 dev_id ; // device instance //identification _hdl dev_h ; // device handle uint32 func ; // functioncode (for IOCTL) LARGE INTEGER offs ; // file offset (for block //devices) void *buf_p ; // pointer to data uint32 buf_sz ; // size ofbuffer pointed to // by p, [bytes] uint32 buf_len ; // length of data in*buf_p, // [bytes] END_EVENT Data: dev_id device instance identification(see note #2 above) dev_h device handle from ‘open’ offs file offset(for block devices) buf_p buffer pointer buf_sz size of buffer, bytesbuf_len number of bytes read (out) *buf_p data read (out) ReturnCMST_NOT_OPE object is not open Status: N CMST_IOERR I/O error Remarks:Reading at end of a stream is usually not considered an error; in thiscase the request is completed with buf_len 0 (or any value less thanbuf_sz).

[5586] EV_DIO_RQ_WRITE Overview: This request is sent to write data to aspecific device driver or file. Description: Write data to device. EventBus EVENT (B_EV_DIO) Definition: cmstat cplt_s ; // completion status //(asynchronous completion) dword ctx ; // originator's context value //(may be IRP) uint32 dev_id ; // device instance // identification _hdldev_h ; // device handle uint32 func ; // function code (for IOCTL)LARGE_INTEGER offs ; // file offset (for block // devices) void *buf_p ;// pointer to data uint32 buf_sz ; // size of buffer pointed to // by p,[bytes] uint32 buf_len ; // length of data in *buf_p. // [bytes]END_EVENT Data: dev_id device instance identification (see note #2above) dev_h device handle from ‘open’ offs file offset (for blockdevices) buf_p pointer to data to be written buf_sz number of bytes towrite buf_len number of bytes written (out) Return CMST_NOT_OPE objectis not open Status: N CMST_IOERR I/O error CMST_FULL media full (forblock devices only)

[5587] EV_DIO_RQ_IOCTL Overview: This request is sent to execute aspecific operation on a device driver. The operation is defined by thedriver. This type of I/O control can be sent to a driver by anotherdriver or an application (user-mode). Description: Execute an I/Ocontrol operation on a device. Event Bus EVENT (B_EV_DIO) Definition:cmstat cplt_s ; // completion status // (asynchronous completion) dwordctx ; // originator's context value // (may be IRP) uint32 dev_id ; //device instance // identification _hdl dev_h ; // device handle uint32func ; // function code (for IOCTL) LARGE_INTEGER offs ; // file offset(for block // devices) void *buf p ; // pointer to data uint32 buf_sz ;// size of buffer pointed to // by p, [bytes] uint32 buf_len ; // lengthof data in *buf_p, // [bytes] END_EVENT Data: dev_id device instanceidentification (see note #2 above) dev_h device handle from ‘open’ funcI/O control function code buf_p pointer to input data and buffer foroutput data buf_sz size of output buffer, bytes buf_len length of inputand output data in bytes Return CMST_NOT_OPE object is not open Status:N CMST_IOERR I/O error CMST NOT_SUP the specified I/O control codePORTED is not supported Remarks: The definition of the I/O controloperations is outside the scope of this definition.

[5588] EV_DIO_RQ_INTERNAL_IOCTL Overview: This request is sent toexecute a specific internal operation on a device driver. The operationis defined by the driver. This type of I/O control can only be sent to adriver from another driver, not by an application (user-mode).Description: Execute an internal I/O control operation on a device.Event Bus EVENT (B_EV_DIO) Definition: cmstat cplt_s ; // completionstatus // (asynchronous completion) dword ctx ; // originator's contextvalue // (may be IRP) uint32 dev_id ; // device instance //identification _hdl dev_h ; // device handle uint32 func ; // functioncode (for IOCTL) LARGE_INTEGER offs ; // file offset (for block //devices) void *buf_p ; // pointer to data uint32 buf_sz ; // size ofbuffer pointed to // by p, [bytes] uint32 buf_len // length of data inThuf_p, // [bytes] END_EVENT Data: dev_id device instance identification(see note #2 above) dev_h device handle from ‘open’ func internal I/Ocontrol function code buf_p pointer to input data and buffer for outputdata buf_sz size of output buffer bytes buf_len length of input andoutput data in bytes Return CMST_NOT_OPE object is not open Status: NCMST_IOERR I/O error GMST_NOT_SUP the specified I/O control PORTED codeis not supported Remarks: The definition of the I/O control operationsis outside the scope of this definition. “internal IOCTL” is a WindowsNT driver term. Device IOCTLs can be submitted to drivers by anapplication or by another driver. Internal IOCTL's can be submitted onlyby other drivers. The main implication is that for internal IOCTL's, thebuffers are always mapped properly in system address space (i.e., thebuffer pointed by buf_p is accessible in arbitrary thread context).

[5589] EV_USBCTL_REQ Overview: This event is used to send vender orclass-specific command requests to a USB device. This request cancomplete synchronously or asynchronously. This event should never besent with the CMEVT_A_SELF_OWNED attribute set. Description: Send avendor or class-specific command to a USB device. Event Bus EVENTX(B_EV_USB_CTLREQ, Definition: EV_USBCTL_REQ, CMEVT_A_SELF_CONTAINED,CMEVT_UNGUARDED) cmstat cplt_s ; // completion status uint32 func ; //request type // (USB_REQ_xxx) uint32 n_resv_bits; // additional functionbits // (not used - must be 0) uint32 code ; // Specifies the USB or //vendor- defined request // code for the device uint32 value ; // Is avalue, specific to // Request, that becomes // part of the USB-defined// setup packet for the // device uint32 index ; // Specifies thedevice- // defined identifier for // the request uint32 data_len //length of the data in the // buffer uint32 data_sz ; // data buffer sizebyte data[1] ; // data buffer END_EVENTX In: attr USB_A_XFER_TO_xxxspecifies the control request direction func function number (must beone of URE_FUNCTION_VEN- DOR_xxx or URB_FUNC- TION_CLASS_xxx) codeSpecifies the USB or vendor-defined request code for the device valuespecific to code value index specifies the device-defined identifier forthe request data_len length of the data in the buffer (only forUSBA_XFER_TO_DE- VICE requests) data_sz data buffer size data databuffer variable size Out: cplt_s completion status len data_len datareturned from USB_A_XFER_TO_HOST requests data Return CMST_PENDINGcallee assumes responsibility to Status: complete the request later(either directly or by sending back an EV_USBCTL_REQ event)

[5590] EV_USB_ENABLE Overview: This event is sent to enable theisochronous USB stream. This request can complete synchronously orasynchronously. This event should never be sent with theCMEVT_A_SELF_OWNED attribute set. Description: Enable isochronous USBstream. Event Bus EVENTX (B_EV_USBCTL, Definition: EV_USB_ENABLE,CMEVT_A_ASYNCCPLT| CMEVT_A_SELF_CONTAINED I CMEVT_A_SYNC,CMEVT_UNGUARDED) cmstat cplt_s ; // completion status uint32 frame_no ;// isochronous frame number to // start from bool32 asap ; // TRUE -start ASAP. FALSE - // use O.frame no to start from uint32 cfg_no //configuration number. Not // used. // (must be −1 undefined) END_EVENTXIn: frame_no isochronous frame number to start from. (only if asap isFALSE) asap TRUE - enable ASAP, ignoring the frame_number. Out: cplt_senable completion status Return CMST_PENDING callee assumesresponsibility to Status: complete the request later (either directly orby sending back an EV_USB_ENABLE event)

[5591] EV_USB_DISABLE Overview: This event is sent to disable theisochronous USB stream. This request can complete synchronously orasynchronously. This event should never be sent with theCMEVT_A_SELF_OWNED attribute set. Description: Disable isochronous USBstream. Event Bus EVENTX (B_EV_USBCTL, Definition: EV_USB_DISABLE,CMEVT_A_ASYNC_CPLT | CMEVT_A_SELF_CONTAINED | CMEVT_A_SYNC,CMEVT_UNGUARDED) cmstat cplt_s ; // completion status uint32 frame_no ;// isochronous frame number to // start from bool32 asap ; // TRUE -start ASAP. FALSE // use 0.frame_no to start from uint32 cfg_no ; //configuration number. Not // used. // (must be −1 undefined) END_EVENTXIn: void Out: cplt_s disable completion status Return CMST_PENDINGcallee assumes responsibility to Status: complete the request later(either directly or by sending back an EV_USB_DISABLE event)

[5592] EV_STM_DATA Overview: This event is sent to submit an isochronousUSB data frame. This request can complete synchronously orasynchronously. This event should never be sent with theCMEVT_A_SELF_OWNED attribute set. Description: Submit an isochronous USBdata frame. Event Bus  EVENTX (B_EV_STM_DATA, Definition:   EV_STM_DATA,  CMEVT_A_ASYNC_CPLT | CMEVT_A_SELF_CONTAINED |  CMEVT_A_SYNC,  CMEVT_UNGUARDED)   cmstat cplt_s ; // data completion status   uint32frame_no ; // current isochronous frame     // number   uint32 data_len;// data length   uint32 data_sz ; // data buffer size   _ctx owner_ctx;// owner context   byte data[1] ; // data buffer (variable size) END_EVENTX In: frame_no current isochronous frame number owner_ctxowner context data_len data length data_sz data buffer size datasubmitted out data data data buffer (variable size) Out: cplt_s currentstatus owner_ctx owner context (caller supplied) Return CMST_PENDINGcallee assumes responsibility to Status: complete the request later(either directly or by sending back an EV_USB_DISABLE event)

[5593] EV_VXD_INIT Overview: This packaging event is used to signal thatthe virtual device was loaded by the system and can perform itsinitialization tasks. Description: Initialize virtual device Event BusEVENT (B_EV_VXD) Definition: dword msg; // control message (value of EAXregister) dword ebx; // value of EBX register dword ecx; // value of ECXregister dword edx; // value of EDX register dword esi; // value of ESIregister dword edi; // value of EDI register dword retval; // value toreturn // (also affects carry flag) END_EVENT Data: void Return CMST_OKinitialized OK Status: any other initialization failed Remarks: Thisevent is issued at thread time, before SYS_DYNAMIC_DEVICE_INIT (fordynamic VxDs) or DEVICE_INIT (for static VxDs). Some EV_VXD_MESSAGEevents may be sent before this event. See Also: EV_VXD_CLEANUP

[5594] EV_VXD_CLEANUP Overview: This packaging event is used to signalthat the virtual device is about to be unloaded by the system and shouldperform its cleanup tasks. Description: Cleanup virtual device Event BusEVENT (B_EV_VXD) Definition: dword msg; // control message (value of EAXregister) dword ebx; // value of EBX register dword ecx; // value of ECXregister dword edx; // value of EDX register dword esi; // value of ESIregister dword edi; // value of EDI register dword retval; // value toreturn // (also affects carry flag) END_EVENT Data: void Return CMST_OKcleanup completed, OK to unload Status: any other cleanup failed-don'tunload Remarks: This event is issued at thread time, after theSYS_DYNAMIC_DEVICE_EXIT. It is not sent for static VxDs. See Also:EV_VXD_INIT

[5595] EV_VXD_MESSAGE Overview: This packaging event is used todistribute raw VxD messages as they are sent by the system. Description:Raw message needs processing Event Bus EVENT (B_EV_VXD) Definition:dword msg; // control message (value of EAX register) dword ebx; //value of EBX register dword ecx; // value of ECX register dword edx; //value of EDX register dword esi; // value of ESI register dword edi; //value of EDI register dword retval; // value to return // (also affectscarry flag) END_EVENT Data: void Return <see Remarsk> cleanup completed,OK to unload Status: Remarks: This event may come in any context,including on disabled interrupts. Upon return, the status and retval areinterpreted the following way: for all control messages except PNP_NEW_DEVNODE and  W32_DEVICEIOCONTROL: If returned status is notCMST_OK: EAX is  set to 0, carry set If returned status is CMST_OK, EAXis set  to retval and If retval is non-zero (VXD_SUCCESS), carry  iscleared If retval is zero (VXD_FAILURE), carry is  set to indicate errorfor the PNP_NEW_DEVNODE and  W32_DEVICEIOCONTROL control  messages Ifreturned status is not CMST_OK: EAX is  set to −1, carry set If returnedstatus is CMST_OK, EAX is set  to retval and If retval is zero (CR_SUCCESS/DEVIOCTL_NOERROR),  carry clear If retval is non-zero,carry is set to indicate  error Note that, on W32_DEVICEIOCONTROL,retval has the following meanings: 0 - success −1 - operation acceptedfor asynchronous processing any other - error

[5596] EV_DRV_INIT Overview: This packaging event is used to signal thatthe driver was loaded by the system and can perform its initializationtasks. Description: Initialize driver Event Bus EVENT (B_EV_DRV)Definition:  NTSTATUS ns; END_EVENT Data: ns status that DriverEntrywill return on failure Return CMST_OK initialized OK Status: any otherinitialization failed Remarks: This event is issued at thread time, IRQlevel passive The value returned from DriverEntry is determined asfollows: if event returned CMST_OK, DriverEntry  returns STATUS_SUCCESS,regardless  of ns if event returned CMST_FAILED,  DriverEntry returns ns(unless ns is  STATUS_SUCCESS, in which case  DriverEntry returns STATUS_UNSUCCESSFUL) if event returned any other status,  DriverEntryreturns  STATUS_UNSUCCESSFUL. See Also: EV_DRV_CLEANUP

[5597] EV_DRV_CLEANUP Overview: This packaging event is used to signalthat the driver is about to be unloaded by the system and should performits cleanup tasks. Description: Cleanup driver Event Bus EVENT(B_EV_DRV) Definition:  NTSTATUS ns; END_EVENT Data: void Return CMST_OKcleanup OK Status: any other cleanup failed Remarks: This event isissued at thread time, IRQ level passive Regardless of the returnedstatus, the driver will be unloaded. See Also: EV_DRV_INIT

Appendix 3. RDX_CNM_DESC Structure

[5598] The connection descriptor comprises a header structure,RDX_CNM_DESC and an array (table) of RDX_CNM_ENTRY structures. When adescriptor is filled in, the tbip field of RDX_CNM_DESC is set to pointto the array of the RDX_CNM_ENTRY structures. typedef structRDX_CNM_DESC { dword sig;  // signature uint16 sz;  // size of theheader uint16 esz;  // size of a single entry uint16 n_entries;  // # ofentries in the table flg16 attr; // table attributes [defined w/table]const void *tblp;  // table of entries or NULL if none } RDX_CNM_DESC;// attributes #define RDX_CNM_A_NONE 0 // entry types #defineRDX_CNM_E_NONE 0 // not initialized #define RDX_CNM_E_SIMP 1 //connection entry // connection table entry typedef structRDX_CNM_ENTRYtag { WORD et; // entry type DWORD et_ctx;  // entry typecontext char *lnamep; // left part name char *ltermp; // left terminalname char *rnamep;  // right part name char *rtermp; // right terminalname WORD attr;  // attributes [RDX_CNM_A_xxx] DWORD ctx;  // attributedependent context DWORD usr_ctx;  // user context } RDX_CNM_ENTRY;

Appendix 4. I_R_ECON Interface

[5599] /*---------------------------------------------------------------------------------*/ /* RFC: Radix Interface */ /* */ /* I_R_ECON.H - RMC ConnectionEnumeration Interface */ /*---------------------------------------------------------------------------------*/ /* Version 1.00 */ /*---------------------------------------------------------------------------------*/ /* Copyright (c) 1998 Object Dynamics Corp. All Rights Reserved. *//* */ /* Use of copyright notice does not imply publication ordisclosure. */ /* THIS SOFTWARE CONTAINS CONFIDENTIAL AND PROPRIETARYINFORMATION    */ /* CONSTITUTING VALUABLE TRADE SECRETS OF OBJECTDYNAMICS CORP., AND    */ /* MAY NOT BE (a) DISCLOSED TO THIRD PARTIES,(b) COPIES IN ANY FORM, */ /* OR (C) USED FOR ANY PURPOSE EXCEPT ASSPECIFICALLY PERMITTED IN */ /* WRITING BY OBJECT DYNAMICS CORP. */ /*------------------------------------------------------------------ */#ifndef _I_R_ECON_H_DEFINED_ #define _I_R_ECON_H_DEFINED_ /* ---Connection Enumeration Definitions----------------------------------------------------- */ // contract id#define CID_R_ECON 0x570 // connection bus BUS (B_R_ECON) RDX_CNM_DESC*cdscp   ; // connection list descriptor char *part_nmp ; // part namechar *term_nmp ; // terminal name _ctx qry_ctx ; // query context _hdlconn_h ; // connection handle char *part_bufp ; // pointer to part namebuffer uint part_buf_sz; // part name buffer size char *term_bufp ; //pointer to terminal name buffer uint term_buf_sz; // terminal namebuffer size char *part2_bufp ; // pointer to part #2 name buffer uintpart2_buf_sz; // part name #2 buffer size char *term2_bufp ; // pointerto terminal #2 name buffer uint term2_buf_sz; // terminal name #2 buffersize bool split_loops; // TRUE to split loop connections END_BUS /* ---Connection Enumeration Vtable Interface----------------------------------------------- */ DECLARE_INTERFACE(I_R_ECON) operation (qry open , B_R_ECON) operation (qry_reset ,B_R_ECON) operation (qry_next , B_R_ECON) operation (qry_prev ,B_R_ECON) operation (qry_curr , B_R_ECON) operation (qry_close ,B_R_ECON) operation (get_info , B_R_ECON) END_DECLARE INTERFACE //I_R_ECON /* --- Description Of Connection Enumeration Interface------------------------------------- */ // on : qry_open // in :cdscp - connection list descriptor //   part_nmp - part name to bematched //   term_nmp - terminal name to be matched //   split_loops -TRUE to present loops as two connections // out : qry_ctx - querycontext for subsequent qry_xxx operations // act : open a new query onthe connection namespace // s : ST_NO_ROOM - too many open queries // on: qry_reset // in : cdscp - connection list descriptor //   qry_ctx -query context from previous qry_xxx operations // out : qry_ctx - querycontext for subsequent qry_xxx operations // act : reset the currentposition to the beginning of the connection sub-space // nb : ST_OK isreturned even if there are no connections defined in the //   connectionsub-space // on : qry_next // in : cdscp - connection list descriptor //  part_bufp - buffer for part name or NULL //   part_buf_sz - size ofpart name buffer, [bytes] //   term_bufp - buffer for terminal name orNULL //   term_buf_sz - size of terminal #2 name buffer, [bytes] //  part2_bufp - buffer for part #2 name or NULL //   part2_buf_sz - sizeof part #2 name buffer, [bytes] //   term2_bufp - buffer for terminal #2name or NULL //   term2_buf_sz - size of terminal name buffer, [bytes]//   qry_ctx - query context from previous qry_xxx operations // out :(*part_bufp) - part name //   (*term_bufp) - terminal name //  (*part2_bufp) - part #2 name //   (*term2_bufp) - terminal #2 name //  qry_ctx - query context for subsequent qry_xxx operations //  conn_h - connection handle // act : get next connection according tothe query context //   the current enumeration context // s :ST_NOT_FOUND - no next connection in the sub-space //   ST_OVERFLOW -buffer too small for part or terminal name // on : qry_prev // in :cdscp - connection list descriptor //   part_bufp - buffer for part nameor NULL //   part_buf_sz - size of part name buffer, [bytes] //  term_bufp - buffer for terminal name or NULL //   term buf_sz - sizeof terminal name buffer, [bytes] //   part2_bufp - buffer for part #2name or NULL //   part2_buf_sz - size of part #2 name buffer, [bytes] //  term2_bufp - buffer for terminal #2 name or NULL //   term2_buf_sz -size of terminal name buffer, [bytes] //   qry_ctx - query context fromprevious qry_xxx operations // out :(*part_bufp) - part name //  (*term_bufp) - terminal name //   (*part2_bufp) - part #2 name //  (*term2_bufp) - terminal #2 name //   qry_ctx - query context forsubsequent qry_xxx operations //   conn_h - connection handle // act :get previous connection according to query context // s : ST_NOT_FOUND -no previous connection in the sub-space //   ST_OVERFLOW - buffer toosmall for part or terminal name // on : qry_curr // in : cdscp -connection list descriptor //   part bufp - buffer for part name or NULL//   part_buf_sz - size of part name buffer, [bytes] //   term_bufp -buffer for terminal name or NULL //   term_buf_sz - size of terminalname buffer, [bytes] //   part2_bufp - buffer for part #2 name or NULL//   part2_buf_sz - size of part #2 name buffer, [bytes] //  term2_bufp - buffer for terminal #2 name or NULL //   term2_buf_sz -size of terminal name buffer, [bytes] //   qry_ctx - query context fromprevious qry_xxx operations // out :(*part_bufp) - part name // out :(*part_bufp) - part name //   (*term_bufp) - terminal name //  (*part2_bufp) - part #2 name //   (*term2_bufp) - terminal #2 name //  conn_h - connection handle // act : get previous connection accordingto query context // s ST_NOT_FOUND - no previous connection in thesub-space //   ST_OVERFLOW - buffer too small for part or terminal name// on : qry_close // in : qry_ctx - query context from previous qry_xxxoperations // out : void // act : close query on the connectionnamespace // nb : “qry_ctx” becomes invalid after this operation // on :get_info // in : cdscp - connection list descriptor //   part_bufp -buffer for part name or NULL //   part_buf_sz - size of part namebuffer, [bytes] //   term_bufp - buffer for terminal name or NULL //  term_bufsz - size of terminal name buffer, Ebytesi //   part2_bufp -buffer for part #2 name or NULL //   part2_buf_sz - size of part #2 namebuffer, [bytes] //   term 2_bufp - buffer for terminal #2 name or NULL//   term2_buf_sz - size of terminal name buffer, [bytes] //   conn_h -connection handle // out :(*part_bufp) - part name //   (*term_bufp) -terminal name //   (*part2_bufp) - part #2 name //   (*term2_bufp) -terminal #2 name // act : get information about particular connection //s : ST_OVERFLOW - buffer too small for part or terminal name #endif //_I_R_ECON_H_DEFINED__

Appendix 5. DM_ARR Part Implementation Design Structures Used

[5600] 1.1. Summary

[5601] This section contains a summary of the main data structures usedin DM_ARR. // virtual property table entry typedef struct VPROP { char*namep; // name of the property uint16 type; // property data type void*valp; // pointer to value uint32 len; // length of the value { VPROP;// virtual terminal table entry typedef struct VTERM { charname[MAX_TERM_NM_SZ]; // virtual terminal name bool connected; // TRUEif terminal connected from outside byte conn_ctx[CONN_CTX_SZ]; //connection context } VTERM; // connection index typedef struct CONN_NDX{ _ctx qry_ctx; // current connection context _hdl vth; // virtualterminal handle } CONN_NDX; // property enumeration state enumS_PROP_QRY { S_PQ_ARRAY, // array properties S_PQ_VIRT_PROP, // virtualproperties S_PQ_SUBS, // properties of subordinates }; // query statefor S_PQ_ARRAY state typedef struct PQ_ARRAY { _ctx pctx; // currentproperty enum. ctx } PG_ARRAY; // query state for S_PQ_VIRT_PROP statetypedef struct PQ_VPROP { _ctx enum_ctx; // current virt. prop. enum ctx} PQ_VPROP; // query state for S_PQ_SUBS state typedef struct PQ_SUBS {_ctx key_pctx; // propety enum. context of subordinate. } PQ_SUBS; //property query state typedef struct PROP_QRY { // enumeration stateS_PROP_QRY state; // query state depending on the state unionPQ_ENUM_STATE { PQ_ARRAY; PQ_VPROP; PQ_SUBS; }; } PROP_QRY; CONN_NDX -Connection Index typedef struct CONN_NDX { _hdl conn_h; // connectionhandle VTERM  vtp;  // virtual terminal instance ID (NULL if notvirtual) bool  left; // TRUE if the array terminal is on the left side// of the connection (as per get_info) } CONN_NDX;

[5602] The DM_ARR uses this structure to maintain the index entry forconnection ←→ terminal map. Instances of this structure are allocated bythe array and added to a handle set using the ClassMagic API.

[5603] No random access is needed to this index and for this reason thehandle values associated with each instance of this structure are notstored anywhere. Only enumeration of these instances is possible whichprovided by the ClassMagic API for handle management.

S_PROP_QRY—Enumeration states

[5604] enum S_PROP_QRY { S_PQ_ARRAY, // array properties S_PQ_VPROP, //virtual properties S_PQ_SUBS, // properties of subordinates };

[5605] The property query state machine uses this enumerated type todetermine the next state in the enumeration. Each state is associatedwith a class of properties currently being enumerated. As the arrayimplements joined name spaces for these classes, the state is needed toidentify the current one.

[5606] The transition is purely sequential in the order in which thesestates are defined. Backward enumeration of properties and thereforebackward state transition are not possible.

PQ_ARRAY—Property Query Context in the S_PQ_ARRAY state

[5607] typedef struct PQ_ARRAY { _ctx   enum_ctx;  // current propertyenum. ctx } PQ_ARRAY;

[5608] This structure represents the property query context inS_PQ_ARRAY state. This is the state in which the properties listed onenumeration are these defined on the array itself, skipping propertieswhose names begin with “._”.

PQ_VPROP—Property Query Context in the S_PQ_VPROP state

[5609] typedef struct PQ_VPROP { _ctx   enum_ctx;  // current virt.prop. enum. ctx } PQ_VPROP;

[5610] This structure represents the property query context inS_PQ_VPROP state. This is the state in which the virtual properties arelisted on enumeration.

[5611] The context is the one returned by the virtual propertyenumeration helper API.

PQ_SUBS—Property Query Context in the S_PQ_SUBS state

[5612] typedef struct PQ_SUBS { _ctx enum_ctx; // part array enumerationcontext bool curr_lst; // TRUE to start from the first property dwordcurr_oid; // current subordinate in the array _ctx curr_qryh; // queryhandle on current subordinate } PQ_SUBS;

[5613] This structure represents the property query context in S_PQ_SUBSstate. This is the state in which the properties of subordinates(elements) of the array are listed on enumeration.

[5614] Both the current subordinate and the property enumeration contexton that subordinate are kept. There is also an indication whether theenumeration has to start from the first property of the current elementor to continue from the current

PROP_QRY—General Property Query Context

[5615] typedef struct PROP_QRY { uint state; // enumeration state flg32attr_mask; // query attributes mask flg32 attr_val; // query attributesvalues union PQ_ENUM_STATE // query state depending on the state {PQ_ARRAY array; PQ_VPROP vprop; PQ_SUBS subs; }; } PROP_QRY;

[5616] This structure represents the composite property query instance.It combines the current state of property enumeration in a queryinstance together with the particular contexts for each individualstate. It is assumed that there is no context shared between differentstates.

Self Data Structure

[5617] BEGIN_SELF DM_ARR_HDR arr; // Part Array from DriverMagic VECONvtc; // virtual terminals container VECON vpc; // virtual propertiescontainer VTDST vtd; // virtual terminal operation distributor VPDSTvpd; // virtual property operation distributor _hdl cnx; // connectionindex owner key _hdl qry; // queries owner key I_META *host_imetap; //host meta-object interface   // used to resolve subordinate name to oidIR_ECON *iecnp; // connection enumeration interface  // used toenumerate the connections in the host RDX_CNM_DESC *cdscp; // connectiondescriptor in the host PROPERTIES RDX_SID sid; // self ID of the hostbool auto_activate; // TRUE to auto-activate bool gen_keys; // TRUE togenerate keys char name [RDX_MAX_PRT_NM_LEN + 1]; // array namechar cls_nm[RDX_MAX_PRT_NM_LEN + 1]; // default class name char _fact[RDX_MAX_TRM_NM_LEN + 1]; // ‘fact’ terminal name char _prop[RDX_MAX_TRM_NM_LEN + 1]; // ‘prop’ terminal name char _conn[RDX_MAX_TRM_NM_LEN + 1]; // ‘conn’ terminal name TERMINALS decl_input(fact, I_A_FACT) decl_input (prop, I_A_PROP) decl_input (conn, I_A_CONN)END_SELF

State Machine Organization

[5618] State machine is used for property enumeration. The input eventsare three: “reset”, “next” and “current”. The machine performssequential state transition in the order in which the states aredefined. Transition to initial state is possible at any state and willhappen if “reset” event is received.

[5619] The input events are declared in the following enumerated type:enum PQ_EVENT { PQ_EV_RESET = 0, PQ_EV_NEXT = 1, PQ_EV_CURR = 2, };

[5620] All events are fed into a state machine controller—a staticfunction responsible to invoke the proper action handler as defined inthe state transition table. The action handler is responsible to performthe state transition before it returns to the controller.

[5621] The prototype of such action handler is shown bellow:

[5622] typedef_stat pq_ahdlr (PROP_QRY *sp, SELF *selfp, B_PROPERTY*bp);

[5623] The state machine event feeder (controller) prototype is shownhere:

[5624] static_stat pq_sm_feed (PROP_QRY *sp, SELF *selfp, uint ev,B_PROPERTY *bp);

[5625] The state transition table associates three action handlers foreach state: “reset”, “next” and “current” action handlers. typedefstruct SM_TBL_ENTRY { pq_ahdlr *reset_hdlrp; pq_ahdlr *next_hdlrp;pq_ahdlr *curr_hdlrp; } SM_TBL_ENTRY;

[5626] State Transition Table: static SM_TBL_ENTRY g_sm_table [] = {  /*PQ_EV_RESET */ /* PQ_EV_NEXT */ /* PQ_EV_NEXT */ /* S_PQ_ARRAY */ah_reset , ah_arr_next , ah_arr_curr , /* S_PQ_VPROP */ ah_reset ,ah_vp_next , ah_vp_curr , /* S_PQ_SUBS */ ah_reset , ah_subs_next ,ah_subs_curr , };

Pseudo-code Life Cycle Constructor

[5627] in: void

[5628] out: void

[5629] initialize property defaults

[5630] create unique owner id for the connection index

[5631] create unique owner id for the property queries

Destructor

[5632] in: void

[5633] out: void

[5634] destroy connection index owner id

[5635] destroy property queries owner id

Activation

[5636] in: void

[5637] out: void

[5638] retrieve host information

[5639] connection descriptor→sp->cdscp

[5640] connection enumeration interface→sp->iecnp

[5641] host's meta object interface→sp->host_imetap

[5642] build connection index

[5643] open query on connections to ‘sp->name’

[5644] enumerate connections, for each connection:

[5645] find virtual terminal with such name

[5646] stop if error

[5647] determine which end of the connection the array (we) are

[5648] get connection table entry using the connection handle returnedby the enumeration

[5649] compute left:=(‘sp->name’ is the left part)

[5650] allocate connection index entry on behalf of the host (using theinterior object ID)→cip

[5651] initialize entry:

[5652] handle of the connection

[5653] virtual terminal ID or NULL if not virtual

[5654] left

[5655] create a handle for the entry using ‘sp->cnx’ and associate itwith the ‘cip’

[5656] close query on connections

[5657] on failure in adding connection to connection index, cleanup:

[5658] enumerate handles with ‘sp->cnx’ onwer, for each

[5659] lock handle, retrieve entry pointer [continue]

[5660] free entry pointer

[5661] destroy handle locked

[5662] return failure status

[5663] construct sub-entities in a composite operation

[5664] construct Part Array instance ‘sp->err’

[5665] construct virtual terminals container ‘sp->vtc’

[5666] construct virtual properties container ‘sp->vpc’

[5667] construct virtual property distributor ‘sp->vpd’

[5668] construct virtual terminal distributor ‘sp->vtd’

[5669] end composite operation

[5670] on composite operation error, cleanup:

[5671] destruct Part Array instance [ignore]

[5672] destruct virtual terminals container [ignore]

[5673] destruct virtual properties container [ignore]

[5674] destruct virtual property distributor [ignore]

[5675] destruct virtual terminal distributor [ignore]

[5676] return failure status

[5677] return ST_OK

Deactivation

[5678] in: void

[5679] out: void

[5680] destruct Part Array instance

[5681] destruct virtual properties container

[5682] destruct virtual terminals container

[5683] destruct virtual property distributor

[5684] destruct virtual terminal distributor

[5685] destroy connection index

[5686] enumerate connection index, for each entry

[5687] lock handle, retrieve index entry

[5688] free

[5689] destroy handle (locked)

[5690] Public: “fact” terminal

[5691] create

[5692] in: attr—attributes [A_FACT_A_XXX]

[5693] namep—class name of part or NULL for default

[5694] id—id to use if A_FACT_A_USE_ID is set

[5695] out: id—id of the created part in the array

[5696] act: Create a part instance in the array

[5697] s: CMST_OK—successful

[5698] CMST_CANT_BIND—the part class was not found

[5699] CMST_ALLOC—not enough memory

[5700] CMST_NO_ROOM—no more ids available (if

[5701] A_FACT_A_USE_ID not set)

[5702] CMST_DUPLICATE—the specified id already exists (if

[5703] A_FACT_A _SE_ID)

[5704] (all others)—specific error occurred during object creation

[5705] if ‘attr’ has A_FACT_A_USE_ID set

[5706] create element in the Part Array using the id in the bus [if_ret]

[5707] else

[5708] create element in the Part Array by generating a id [if_ret]

[5709] store element id→el_id

[5710] retrieve object id of the new element→el_oid

[5711] retrieve our interior oid→int_oid

[5712] enumerate connection index using ‘sp->cnx’, for each entry in theindex:

[5713] lock handle to retrieve entry

[5714] retrieve connection table information from ‘cip->h’ (using‘sp->i_ecnp’)

[5715] part1

[5716] term1

[5717] part2

[5718] term2

[5719] if connection is to a virtual terminal (‘cip->vtp’ !=NULL):

[5720] use ClassMagic connection broker API to connect the element toterminal to the terminal on the DM_ARR interior:

[5721] oid1:=int_oid

[5722] term1:=cip->vtp->namep

[5723] oid2:=el_oid

[5724] term2:=cip->vtp->namep

[5725] conn_id:=el_id

[5726] [cleanup: destroy Part Array element]

[5727] else connect to terminal in the host's interior

[5728] retrieve object id of the part in the interior from thesp->host_imetap:

[5729] part name:=cip->left ? part2: part1

[5730] part name→part oid

[5731] use Part Array connection broker API to connect the elementterminal to the terminal in the host's interior:

[5732] array id:=element array id

[5733] array term:=left ? term1: term2

[5734] oid:=part oid

[5735] term name:=left ? term2: term1

[5736] unlock handle

[5737] [common cleanup: destroy Part Array element]

[5738] set all current virtual properties to the new element

[5739] enumerate virtual property container, for each virtual property

[5740] use part array API to set the virtual property value into thearray element

[5741] auto-activate new element if needed

[5742] pass ‘el_id’ back to the caller if needed

[5743] return ST_OK

[5744] destroy

[5745] in: id—id of part to destroy

[5746] out: void

[5747] act: destroy a part instance in the array

[5748] s: CMST_OK—successful

[5749] CMST_NOT_FOUND—the id could not be found

[5750] (all others)—an intermittent error occurred during destruction

[5751] destroy Part Array element by id (count on automatic connectioncleanup)

[5752] return ST_OK

[5753] activate

[5754] in: id—id of part to activate

[5755] out: void

[5756] act: activate a part instance in the array

[5757] s: CMST_OK—successful

[5758] CMST_NOT_FOUND—the id was not found

[5759] CMST_NO_ACTION—the object is already active

[5760] CMST_REFUSE—mandatory properties have not been set or terminalsnot connected

[5761] (all others)—as returned by part's activator

[5762] redirect to Part Array API

[5763] deactivate

[5764] in: id—id of part to deactivate

[5765] out: void

[5766] act: deactivate a part instance in the array

[5767] s: CMST_OK—successful

[5768] CMST_NOT_FOUND—the id was not found

[5769] (all others)—as returned by part's deactivator

[5770] redirect to Part Array API

[5771] get_first

[5772] in: void

[5773] out: id—id of the first part in the array

[5774] ctx—enumeration context for subsequent get next

[5775] act: get the first part in the part array

[5776] s: CMST_OK—successful

[5777] CMST_NOT_FOUND—the array has no parts

[5778] redirect to Part Array API (qry_reset and then qry_next)

[5779] get_next

[5780] in: ctx—enumeration context from previous get_xxx

[5781] out: id—id of next part in the array

[5782] ctx—enumeration context for subsequent get_xxx

[5783] act: get the next part in the part array

[5784] s: CMST_OK—successful

[5785] CMST_NOT_FOUND—the array has no more parts

[5786] redirect to Part Array API

[5787] Public: “prop” terminal

[5788] get

[5789] in: id—id of part in the array

[5790] namep—null-terminated property name

[5791] type—type of the property to retrieve or CMPRP_T_NONE for any

[5792] bufp—pointer to buffer to receive property or NULL

[5793] buf_sz—size in bytes of *bufp

[5794] out:(*bufp)—property value

[5795] val_len—length in bytes of property value

[5796] act: get the value of a property from a part in the array

[5797] s: CMST_OK—successful

[5798] CMST_NOT_FOUND—the property could not be found or the id isinvalid

[5799] CMST_REFUSE—the data type does not match the expected type

[5800] CMST_OVERFLOW—the buffer is too small to hold the property value

[5801] redirect to Part Array API

[5802] set

[5803] in: id—id of part in the array

[5804] namep—null-terminated property name

[5805] type—type of the property to set

[5806] bufp—pointer to buffer containing property value

[5807] val_len—size in bytes of property value

[5808] out: void

[5809] act: set the value of a property of a part in the array

[5810] s: CMST_OK—successful

[5811] CMST_NOT_FOUND—the property could not be found or the id isinvalid

[5812] CMST_REFUSE—the property type is incorrect or the property cannotbe changed while the part is in an active state

[5813] CMST_OUT_OF_RANGE—the property value is not within the range ofallowed values for this property

[5814] CMST_BAD_ACCESS—there has been an attempt to set a read-onlyproperty

[5815] CMST_OVERFLOW—the property value is too large

[5816] CMST_NULL_PTR—the property name pointer is NULL or an attempt wasmade to set default value for a property that does not have a defaultvalue

[5817] nb: for string properties, val_len must include the terminatingzero

[5818] nb: If bufp is NULL, the function tries to reset the propertyvalue to its default.

[5819] redirect to Part Array API

[5820] chk

[5821] in: id—id of part in the array

[5822] namep—null-terminated property name

[5823] type—type of the property value to check

[5824] bufp—pointer to buffer containing property value

[5825] val_len—size in bytes of property value

[5826] out: void

[5827] act: check if a property can be set to the specified value

[5828] s: CMST_OK—successful

[5829] CMST_NOT_FOUND—the property could not be found or the id isinvalid

[5830] CMST_REFUSE—the property type is incorrect or the property cannotbe changed while the part is in an active state

[5831] CMST_OUT_OF_RANGE—the property value is not within the range ofallowed values for this property

[5832] CMST_BAD_ACCESS—there has been an attempt to set a read-onlyproperty

[5833] CMST_OVERFLOW—the property value is too large

[5834] CMST_NULL_PTR—the property name pointer is NULL or an attempt wasmade to set default value for a property that does not have a defaultvalue

[5835] redirect to Part Array API

[5836] get_info

[5837] in: id—id of part in the array

[5838] namep—null-terminated property name

[5839] out: type type of property [CMPRP_T_XXX]

[5840] attr—property attributes [CMPRP_A_XXX]

[5841] act: retrieve the type and attributes of the specified property

[5842] s: CMST_OK—successful

[5843] CMST_NOT_FOUND—the property could not be found or the id isinvalid

[5844] retrieve element oid

[5845] redirect to ClassMagic API

[5846] qry_open

[5847] in: id—id of part in the array

[5848] namep—query string (must be “*”)

[5849] attr—attribute values of properties to include

[5850] attr_mask—attribute mask of properties to include

[5851] out: qryh—query handle

[5852] act: open a query to enumerate properties on a part in the arraybased upon the specified attribute mask and values or CMPRP_A_NONE toenumerate all properties

[5853] s: CMST_OK—successful

[5854] CMST_NOT_FOUND—the id could not be found or is invalid

[5855] CMST_NOT_SUPPORTED—the specified part does not support propertyenumeration or does not support nested or concurrent propertyenumeration

[5856] nb: To filter by atrributes, specifiy the set of attributes inattr_mask and their desired values in attr. During the enumeration, abit-wise AND is performed between the actual attributes of each propertyand the value of attr_mask; the result is then compared to attr. Ifthere is an exact match, the property will be enumerated.

[5857] nb: To enumerate all properties of a part, specifiy the querystring as “*” and attr_mask and attr as 0.

[5858] nb: The attribute mask can be one or more of the following:

[5859] CMPRP_A_NONE—not specified

[5860] CMPRP_A_PERSIST—persistent property

[5861] CMPRP_A_ACTIVETIME—property can be modified while active

[5862] CMPRP_A_MANDATORY—property must be set before activation

[5863] CMPRP_A_RDONLY—read-only property

[5864] CMPRP_A_UPCASE—force uppercase

[5865] CMPRP_A_ARRAY—property is an array

[5866] retrieve element oid

[5867] redirect to ClassMagic API

[5868] qry_first

[5869] in: qryh—query handle returned on qryopen

[5870] bufp—storage for the returned property name or NULL

[5871] buf_sz—size in bytes of *bufp

[5872] out:(*bufp)—property name (if bufp not NULL)

[5873] act: retrieve the first property in a query

[5874] s: CMST_OK—successful

[5875] CMST_NOT_FOUND—no properties found matching current query

[5876] CMST_OVERFLOW—buffer is too small for property name

[5877] retrieve element oid

[5878] redirect to ClassMagic API

[5879] qry_next

[5880] in: qryh—query handle returned on qry_open

[5881] bufp—storage for the returned property name or NULL

[5882] buf_sz—size in bytes of *bufp

[5883] out:(*bufp)—property name (if bufp not NULL)

[5884] act: retrieve the next property in a query

[5885] s: CMST_OK—successful

[5886] CMST_NOT_FOUND—there are no more properties that match the querycriteria

[5887] CMST_OVERFLOW—buffer is too small for property name

[5888] retrieve element oid

[5889] redirect to ClassMagic API

[5890] qry_curr

[5891] in: qryh—query handle returned on qry_open

[5892] bufp—storage for the returned property name

[5893] buf_sz—size in bytes of *bufp

[5894] out:(*bufp)—property name (if bufp not NULL)

[5895] act: retrieve the current property in a query

[5896] s: CMST_OK—successful

[5897] CMST_NOT_FOUND—no current property (e.g. after a call toqry_open)

[5898] CMST_OVERFLOW—buffer is too small for property name

[5899] retrieve element oid

[5900] redirect to ClassMagic API

[5901] Public: “conn” terminal

[5902] connect

[5903] in: id1—id of part 1

[5904] term1_namep—terminal name of part 1

[5905] id2—id of part 2

[5906] term2_namep—terminal name of part 2

[5907] conn_id—connection id to represent this connection

[5908] out: void

[5909] act: connect two terminals between parts in the array

[5910] s: CMST_OK—successful

[5911] CMST_REFUSE—there has been an interface or direction mismatch oran attempt has been made to connect a non-active-time terminal when thepart is in an active state

[5912] CMST_NOT_FOUND—at least one of the terminals could not be foundor one of the ids is invalid

[5913] CMST_OVERFLOW—an implementation imposed restriction in the numberof connections has been exceeded

[5914] nb: id1 and id2 may be the same to connect two terminals on thesame part

[5915] retrieve second element oid

[5916] redirect to Part Array API

[5917] disconnect

[5918] in: id1—id of part 1

[5919] term1_namep—terminal name of part 1

[5920] id2—id of part 2

[5921] term2_namep—terminal name of part 2

[5922] conn_id—connection id to represent this connection

[5923] out: void

[5924] act: disconnect terminals between parts in the array

[5925] s: CMST_OK—successful

[5926] retrieve second element oid

[5927] redirect to Part Array API

[5928] Custom: Terminal Mechanism (Exterior)

[5929] acquire

[5930] in: namep—terminal name or NULL

[5931] (hdl)—terminal handle (if namep==NULL)

[5932] conn_id—connection id or NO_ID

[5933] out: context—connection context

[5934] type—terminal type [TERM_TYPE]

[5935] card—cardinality

[5936] sync—terminal synchronosity

[5937] dir—terminal direction

[5938] attr—terminal attributes

[5939] conn_h—connection handle

[5940] act: acquire connection context

[5941] s: ST_NOT_FOUND—terminal not found

[5942] ST_REFUSE—component is in inappropriate state

[5943] ST_NO_ROOM—terminal cardinality exhausted

[5944] ST_NOP—operation impossible at this time

[5945] ST_OVERFLOW—provided space for context is not enough

[5946] nb: The connection context structures are ‘tagged’, i.e. thefirst 8 bits contain an identifier of the structure. Any implementationmust check and recognize the ‘tag’ before it can operate with the restof the structure.

[5947] valchk: namep !=NULL

[5948] invoke default terminal implementation

[5949] return if anything different than ST_NOT_FOUND

[5950] invoke term_name_replace internal method

[5951] srcp=bp

[5952] tgtp=local copy of ‘*bp’

[5953] term_nm=stack buffer

[5954] term_nm_sz=sizeof (term_nm)

[5955] backward=FALSE

[5956] invoke default terminal implementation again

[5957] return if anything different than ST_NOT_FOUND

[5958] resolve terminal by name in the virtual terminals container

[5959] if not found return ST_NOP

[5960] if error return error

[5961] redirect operation to the exterior virtual terminal helper

[5962] release

[5963] in: namep—terminal name or NULL

[5964] (hdl)—terminal handle (if namep==NULL)

[5965] (conn_id)—connection id or NO_ID

[5966] (conn_h)—connection handle or NO_HDL

[5967] out: void

[5968] act: release connection context

[5969] s: ST_NO_ACTION—the specified context was not acquired

[5970] ST_REFUSE—component is in inappropriate state

[5971] ST_NOT_FOUND—terminal not found

[5972] nb: either ‘connid’ or ‘conn_h’ should contain a value for thisoperation to succeed; if both contain values, ‘conn_id’ is ignored.

[5973] valchk: namep !=NULL

[5974] invoke default terminal implementation

[5975] return if anything different than ST_NOT_FOUND

[5976] invoke term_name_replace internal method

[5977] srcp=bp

[5978] tgtp=local copy of ‘*bp’

[5979] term_nm=stack buffer

[5980] term_nm_sz =sizeof (term_nm)

[5981] backward=FALSE

[5982] invoke default terminal implementation again

[5983] return if anything different than ST_NOT_FOUND

[5984] resolve terminal by name in the virtual terminals container

[5985] if not found return ST_NOP

[5986] if error return error

[5987] redirect operation to the exterior virtual terminal helper

[5988] connect

[5989] in: namep—terminal name or NULL

[5990] (hdl)—terminal handle (if namep==NULL)

[5991] type—target terminal type [TERM_TYPE]

[5992] sync—target terminal synchronosity

[5993] dir—target terminal direction

[5994] attr—target terminal attributes

[5995] context—connection context of the terminal to connect to

[5996] (conn_id)—connection id or NO_ID

[5997] (conn_h)—connection handle or NO_HDL

[5998] out: void

[5999] act: connect terminal to another terminal

[6000] s: ST_REFUSE—interface mismatch (e.g., unacceptable‘contract_id’) or inappropriate state

[6001] ST_NOP—operation impossible at this time

[6002] ST_NOT_FOUND—terminal not found

[6003] ST_OVERFLOW—implementation imposed restriction in # ofconnections

[6004] nb: either ‘conn_id’ or ‘conn_h’ should contain a value for thisoperation to succeed; if both contain values, ‘conn_id’ is ignored.

[6005] nb: The connection context structures are ‘tagged’, i.e. thefirst 8 bits contain an identifier of the structure. Any implementationmust check and recognize the ‘tag’ before it can operate with the restof the structure.

[6006] valchk: namep !=NULL

[6007] invoke default terminal implementation

[6008] return if anything different than ST_NOT_FOUND

[6009] invoke term_name_replace internal method

[6010] srcp=bp

[6011] tgtp=local copy of ‘*bp’

[6012] term_nm=stack buffer

[6013] term_nm_sz=sizeof (term_nm)

[6014] backward=FALSE

[6015] invoke default terminal implementation again

[6016] return if anything different than ST_NOT_FOUND

[6017] resolve terminal by name in the virtual terminals container

[6018] if not found return ST_NOP

[6019] if error return error

[6020] invoke operation on the exterior virtual terminal helper

[6021] redirect to virtual terminal distributor

[6022] skip_err=FALSE

[6023] disconnect

[6024] in: namep—terminal name or NULL

[6025] (hdl)—terminal handle (if namep==NULL)

[6026] (conn_id)—connection id or NO_ID

[6027] (conn_h)—connection handle or NO_HDL

[6028] out: void

[6029] act: disconnect terminal

[6030] s: ST_REFUSE—component is in inappropriate state

[6031] ST_NOP—operation impossible at this time

[6032] nb: either ‘conn_id’ or ‘conn_h’ should contain a value for thisoperation to succeed; if both contain values, ‘conn_id’ is ignored.

[6033] valchk: namep !=NULL

[6034] invoke default terminal implementation

[6035] return if anything different than ST_NOT_FOUND

[6036] invoke term_name_replace internal method

[6037] srcp=bp

[6038] tgtp=local copy of ‘*bp’

[6039] term_nm=stack buffer

[6040] term_nm_sz=sizeof (term_nm)

[6041] backward=FALSE

[6042] invoke default terminal implementation again

[6043] return if anything different than ST_NOT_FOUND

[6044] resolve terminal by name in the virtual terminals container

[6045] if not found return ST_NOP

[6046] if error return error

[6047] invoke operation on the exterior virtual terminal helper

[6048] redirect to virtual terminal distributor

[6049] skip_err=FALSE

[6050] get_info

[6051] in: namep—terminal name or NULL

[6052] (hdl)—terminal handle (if namep==NULL)

[6053] out: type—terminal type [TERM_TYPE]

[6054] card—terminal cardinality (static, not current)

[6055] n_conn—current # of connections

[6056] sync—terminal synchronosity

[6057] attr—terminal attributes

[6058] dir—terminal direction

[6059] act: return information about specified terminal

[6060] s: ST_NOT_FOUND—terminal not found

[6061] valchk: namep !=NULL

[6062] invoke default terminal implementation

[6063] return if anything different than ST_NOT_FOUND

[6064] invoke term_name_replace internal method

[6065] srcp=bp

[6066] tgtp=local copy of ‘*bp’

[6067] term_nm=stack buffer

[6068] term_nm_sz=sizeof (term_nm)

[6069] backward=FALSE

[6070] invoke default terminal implementation again

[6071] return if anything different than ST_NOT_FOUND

[6072] resolve terminal by name in the virtual terminals container

[6073] if not found return ST_NOP

[6074] if error return error

[6075] redirect operation to the exterior virtual terminal helper

[6076] qry_open

[6077] in: namep—query string

[6078] out: qry_ctx—query context for subsequent qry_xxx operations

[6079] act: open query on terminal namespace

[6080] s: ST_NO_ROOM—too many open queries

[6081] ST_BAD_SYNTAX—bad query syntax

[6082] nb: the query syntax is defined by the particular implementation

[6083] redirect to the default implementation

[6084] qry_get_first

[6085] in: namep—buffer for name or NULL

[6086] (name_sz)—size of buffer, [bytes]

[6087] qry_ctx—query context from previous qry_xxx operation

[6088] out:(* namep)—terminal name

[6089] qry_ctx—query context for subsequent qry_xxx operation

[6090] act: get first matching terminal name

[6091] s: ST_NOT_FOUND—no matching terminals

[6092] invoke default implementation

[6093] invoke term_name_replace

[6094] srcp=bp

[6095] tgtp=bp

[6096] bufp=bp->namep

[6097] buf_sz=bp->name_sz

[6098] backward=TRUE

[6099] return ST_OK

[6100] qry_get_last

[6101] in: namep—buffer for name or NULL

[6102] (name_sz)—size of buffer, [bytes]

[6103] qry_ctx—query context from previous qry_xxx operation

[6104] out:(*namep)—terminal name

[6105] qry_ctx—query context for subsequent qry_xxx operation

[6106] act: get last matching terminal name

[6107] s: St_NOT_FOUND—no matching terminals

[6108] invoke default implementation

[6109] invoke term_name_replace

[6110] srcp=bp

[6111] tgtp=bp

[6112] bufp=bp->namep

[6113] buf_sz=bp->name_sz

[6114] backward=TRUE

[6115] return ST_OK

[6116] qry_get_next

[6117] in: namep—buffer for name or NULL

[6118] (name_sz)—size of buffer, [bytes]

[6119] qry_ctx—query context from previous qry_xxx operation

[6120] out:(*namep)—terminal name

[6121] qry_ctx—query context for subsequent qry_xxx operation

[6122] act: get next matching terminal name

[6123] s: ST_NOT_FOUND—no more matching terminals

[6124] invoke default implementation

[6125] invoke term_name_replace

[6126] srcp=bp

[6127] tgtp=bp

[6128] bufp=bp->namep

[6129] buf_sz=bp->name_sz

[6130] backward=TRUE

[6131] return ST_OK

[6132] qry_get_prev

[6133] in: namep—buffer for name or NULL

[6134] (name_sz)—size of buffer, [bytes]

[6135] qry_ctx—query context from previous qry_xxx operation

[6136] out:(* namep)—terminal name

[6137] id—alternative id (if any) or NO_ID

[6138] qry_ctx—query context for subsequent qry_xxx operation

[6139] act: get previous matching terminal name

[6140] s: ST_NOT_FOUND—no more matching terminals

[6141] invoke default implementation

[6142] invoke term_name_replace

[6143] srcp=bp

[6144] tgtp=bp

[6145] bufp=bp->namep

[6146] buf_sz=bp->name_sz

[6147] backward=TRUE

[6148] return ST_OK

[6149] qry_get_curr

[6150] in: namep—buffer for name or NULL

[6151] (name_sz)—size of buffer, [bytes]

[6152] qry_ctx—query context from previous qry_xxx ration

[6153] out:(*namep)—terminal name

[6154] id—alternative id (if any) or NO_ID

[6155] act: get current terminal name in query

[6156] nb: qry_ctx is unchanged

[6157] on qry_close

[6158] in: qry_ctx—query context from qry_open or another qry_xxxoperation

[6159] out: void

[6160] act: close query on terminal name space

[6161] invoke default implementation

[6162] invoke term_name_replace

[6163] srcp=bp

[6164] tgtp=bp

[6165] bufp=bp->namep

[6166] buf_sz=bp->name_sz

[6167] backward=TRUE

[6168] return ST_OK

[6169] qry_close

[6170] in: qry_ctx—query context from qry_open or another qry_xxxoperation

[6171] out: void

[6172] act: close query on terminal name space

[6173] redirect to the default implementation

[6174] Custom: Terminal Mechanism (Interior)

[6175] acquire

[6176] in: namep—terminal name or NULL

[6177] (hdl)—terminal handle (if namep==NULL)

[6178] conn_id—connection id or NO_ID

[6179] out: context—connection context

[6180] type—terminal type [TERM_TYPE]

[6181] card—cardinality

[6182] sync—terminal synchronosity

[6183] dir—terminal direction

[6184] attr—terminal attributes

[6185] conn_h—connection handle

[6186] act: acquire connection context

[6187] s: ST_NOT_FOUND—terminal not found

[6188] ST_REFUSE—component is in inappropriate state

[6189] ST_NO_ROOM—terminal cardinality exhausted

[6190] ST_NOP—operation impossible at this time

[6191] ST_OVERFLOW—provided space for context is not enough

[6192] nb: The connection context structures are ‘tagged’, i.e. thefirst 8 bits contain an identifier of the structure. Any implementationmust check and recognize the ‘tag’ before it can operate with the restof the structure.

[6193] resolve terminal by name in the virtual terminals container[if_ret]

[6194] redirect operation to the interior virtual terminal helper

[6195] release

[6196] in: namep—terminal name or NULL

[6197] (hdl)—terminal handle (if namep==NULL)

[6198] (conn_id)—connection id or NO_ID

[6199] (conn_h)—connection handle or NO_HDL

[6200] out: void

[6201] act: release connection context

[6202] s: ST_NO_ACTION—the specified context was not acquired

[6203] ST_REFUSE—component is in inappropriate state

[6204] ST_NOP—operation impossible at this time

[6205] St_NOT_FOUND—terminal not found

[6206] nb: either ‘conn_id’ or ‘conn_h’ should contain a value for thisoperation to succeed; if both contain values, ‘conn_id’ is ignored.

[6207] resolve terminal by name in the virtual terminals container[if_ret]

[6208] redirect operation to the interior virtual terminal helper

[6209] connect

[6210] in: namep—terminal name or NULL

[6211] (hdl)—terminal handle (if namep==NULL)

[6212] type—target terminal type [TERM_TYPE]

[6213] sync—target terminal synchronosity

[6214] dir—target terminal direction

[6215] attr—target terminal attributes

[6216] context—connection context of the terminal to connect to

[6217] (conn_id)—connection id or NO_ID

[6218] (conn_h)—connection handle or NO_HDL

[6219] out: void

[6220] act: connect terminal to another terminal

[6221] s: ST_REFUSE—interface mismatch (e.g., unacceptable‘contract_id’) or inappropriate state

[6222] ST_NOT_FOUND—terminal not found

[6223] ST_NOP—operation impossible at this time

[6224] ST_OVERFLOW—implementation imposed restriction in # ofconnections

[6225] nb: either ‘conn_id’ or ‘conn_h’ should contain a value for thisoperation to succeed; if both contain values, ‘conn_id’ is ignored.

[6226] nb: The connection context structures are ‘tagged’, i.e. thefirst 8 bits contain an identifier of the structure. Any implementationmust check and recognize the ‘tag’ before it can operate with the restof the structure.

[6227] resolve terminal by name in the virtual terminals container[if_ret]

[6228] redirect operation to the interior virtual terminal helper

[6229] disconnect

[6230] in: namep—terminal name or NULL

[6231] (hdl)—terminal handle (if namep==NULL)

[6232] (conn_id)—connection id or NO_ID

[6233] (conn_h)—connection handle or NO_HDL

[6234] out: void

[6235] act: disconnect terminal

[6236] s: ST_REFUSE—component is in inappropriate state

[6237] ST_NOP—operation impossible at this time

[6238] nb: either ‘conn_id’ or ‘conn_h’ should contain a value for thisoperation to succeed; if both contain values, ‘conn_id’ is ignored.

[6239] resolve terminal by name in the virtual terminals container[if_ret]

[6240] redirect operation to the interior virtual terminal helper

[6241] get_info

[6242] in: namep—terminal name or NULL

[6243] (hdl)—terminal handle (if namep==NULL)

[6244] out: type—terminal type [TERM_TYPE]

[6245] card—terminal cardinality (static, not current)

[6246] n_conn—current # of connections

[6247] sync—terminal synchronosity

[6248] attr—terminal attributes

[6249] dir—terminal direction

[6250] act: return information about specified terminal

[6251] s: St_NOT_FOUND—terminal not found

[6252] resolve terminal by name in the virtual terminals container[if_ret]

[6253] redirect operation to the interior virtual terminal helper

[6254] qry_open

[6255] in: namep—query string

[6256] out: qry_ctx—query context for subsequent qry_xxx operations

[6257] act: open query on terminal namespace

[6258] s: ST_NO_ROOM—too many open queries

[6259] ST_BAD_SYNTAX—bad query syntax

[6260] nb: the query syntax is defined by the particular implementation

[6261] compare ‘namep’ with “*”

[6262] return ST_BAD_SYNTAX if no match

[6263] invoke ‘get_first’ operation on the virtual terminal container

[6264] if ST_OK or ST_NOT_FOUND return ST_OK

[6265] if error return error

[6266] pass returned context as qry_ctx

[6267] return ST_OK

[6268] qry_get_first

[6269] in: namep—buffer for name or NULL

[6270] (name_sz)—size of buffer, [bytes]

[6271] qry_ctx—query context from previous qry_xxx operation

[6272] out:(*namep)—terminal name

[6273] qry_ctx—query context for subsequent qry_xxx operation

[6274] act: get first matching terminal name

[6275] s: ST_NOT_FOUND—no matching terminals

[6276] redirect to ‘get_first’ operation on the virtual terminalcontainer

[6277] pass virtual terminal name if needed

[6278] pass returned context as qry_ctx

[6279] qry_get_last

[6280] in: namep—buffer for name or NULL

[6281] (name_sz)—size of buffer, [bytes]

[6282] qry_ctx—query context from previous qry_xxx operation

[6283] out:(*namep)—terminal name

[6284] qry_ctx—query context for subsequent qry_xxx operation

[6285] act: get last matching terminal name

[6286] s: ST_NOT_FOUND—no matching terminals

[6287] return ST_NOT_SUPPORTED

[6288] qry_get_next

[6289] in: namep—buffer for name or NULL

[6290] (name_sz)—size of buffer, [bytes]

[6291] qry_ctx—query context.from previous qry_xxx operation

[6292] out:(*namep)—terminal name

[6293] qry_ctx—query context for subsequent qry_xxx operation

[6294] act: get next matching terminal name

[6295] s: St_NOT_FOUND—no more matching terminals

[6296] redirect to ‘get_next’ operation on the virtual terminalcontainer

[6297] pass virtual terminal name if needed

[6298] pass returned context as qry_ctx

[6299] qry_get_prev

[6300] in: namep buffer—for name or NULL

[6301] (name_sz)—size of buffer, [bytes]

[6302] qry_ctx—query context from previous qry_xxx operation

[6303] out:(*namep)—terminal name

[6304] id—alternative id (if any) or NO_ID

[6305] qry_ctx—query context for subsequent qry_xxx operation

[6306] act: get previous matching terminal name

[6307] s: ST_NOT_FOUND—no more matching terminals

[6308] return ST_NOT_SUPPORTED

[6309] qry_get_curr

[6310] in: namep—buffer for name or NULL

[6311] (name_sz)—size of buffer, [bytes]

[6312] qry_ctx—query context from previous qry_xxx ration

[6313] out:(*namep)—terminal name

[6314] id—alternative id (if any) or NO_ID

[6315] act: get current terminal name in query

[6316] nb: qry_ctx is unchanged

[6317] on qry_close

[6318] in: qry_ctx—query context from qry_open or another qry_xxxoperation

[6319] out: void

[6320] act: close query on terminal name space

[6321] redirect to ‘get_curr’ operation on the virtual terminalcontainer

[6322] pass virtual terminal name if needed

[6323] qry_close

[6324] in: qry_ctx—query context from qry_open or another qry_xxxoperation

[6325] out: void

[6326] act: close query on terminal name space

[6327] return ST_OK

[6328] Custom: Property Mechanism

[6329] get

[6330] in: bp->namep—name/id of property to get or NULL

[6331] (bp->hdl)—property handle (if ‘bp->namep’ is NULL)

[6332] (bp->ndx)—index of the array element if needed

[6333] bp->type—expected value type or PROP_T_NONE for any

[6334] bp->p—buffer for property value or NULL

[6335] bp->sz)—size of buffer (if bp->p!=NULL)

[6336] out: bp->type—actual type of value (if bp->type==PROP_T_NONE)

[6337] (*bp->p)—property value (if bp->p!=NULL)

[6338] bp->len—actual length of value, [bytes], incl. any terminators

[6339] act: get property value

[6340] s: St_NOT_FOUND—property not found ST_REFUSE—incorrect propertytype ST_OVERFLOW—buffer too small for property value

[6341] nb: bp->sz must be provided for all property types, includedfixed-size

[6342] process properties defined on the array:

[6343] invoke default property mechanism (ClassMagic) and return statusif anything different than ST_NOT_FOUND

[6344] if array element property (‘bp->namep[0]’ is ‘[’)

[6345] if extracting the id value between the ‘[’ and ‘]’ successful:

[6346] redirect the operation to Part Array:

[6347] convert the string value between ‘[’ and ‘]’ to element id

[6348] strip the “[xxx]” and, if present, the ‘.’ after that

[6349] use element id calculated above and redirect to the Part ArrayAPI

[6350] else if property is broadcast (name starts with “[*]”)

[6351] redirect operation to virtual property distributor helperstripping the “[*]” and the ‘.’ after that if present

[6352] else return ST_NOT_FOUND

[6353] if ‘bp->namep’ is ‘._repeated’

[6354] return ST_NOT_SUPPORTED

[6355] find virtual property with the same name as the one requested bythe operation [if_ret]

[6356] redirect operation to virtual property

[6357] set

[6358] in: bp->namep—name/id of property to set or NULL

[6359] (bp->hdl)—property handle (if ‘bp->namep’ is NULL)

[6360] (bp->ndx)—index of the array/vector element if needed

[6361] bp->type—property type or PROP_T_NONE if unknown

[6362] bp->p—buffer containing property value, NULL for default

[6363] bp->len—actual length of value, [bytes], or 0 for auto

[6364] out: void

[6365] act: set property value

[6366] s: ST_NOT_FOUND—property not found

[6367] ST_REFUSE—incorrect property type

[6368] ST_BAD_VALUE—bad property value

[6369] ST_BAD_ACCESS—attempt to set a read-only property

[6370] ST_OVERFLOW—property value too long

[6371] nb: bp->len==0 is allowed only on fixed-size types, ASCIZ andUNICODEZ

[6372] invoke default property mechanism (ClassMagic)

[6373] return if anything but ST_NOT_FOUND

[6374] if array element property (‘bp->namep[0]’ is ‘[’)

[6375] if extracting id value between the ‘[’ and ‘]’ successful:

[6376] convert the string value between ‘[’ and ‘]’ to element id

[6377] strip the “[xxx]” and, if present, the ‘.’ after that

[6378] use element id calculated above and redirect to the Part ArrayAPI

[6379] else if property is broadcast (name starts with “[*]”)

[6380] find virtual property with name the string after the “[*]”

[6381] if no such property exists, create it

[6382] invoke same operation on the virtual property

[6383] redirect operation to the virtual property distributor

[6384] else return St_NOT_FOUND

[6385] if ‘bp->namep’ is ‘._repeated’

[6386] create virtual terminal with name the value of the property

[6387] return status of the creation operation

[6388] find virtual property with the same name as the requested by theoperation

[6389] if no such property exists, create it

[6390] redirect to the same operation on the virtual property

[6391] redirect to the same operation on the virtual propertydistributor

[6392] chk

[6393] in: bp->namep—name/id of property to check or NULL

[6394] (bp->hdl)—property handle (if ‘bp->namep’is NULL)

[6395] (bp->ndx)—index of the array element if needed

[6396] bp->type—property type or PROP_T_NONE if unknown

[6397] bp->p—buffer containing property value, NULL for default

[6398] bp->len—actual length of value, [bytes], or 0 for auto

[6399] out: void

[6400] act: check property value

[6401] s: ST_NOT_FOUND—property not found

[6402] ST_REFUSE—incorrect property type

[6403] ST_BAD_VALUE—bad property value

[6404] ST_BAD_ACCESS—attempt to set a read-only property

[6405] ST_OVERFLOW—property value too long

[6406] nb: bp->len==0 is allowed only on fixed-size types, ASCIZ andUNICODEZ

[6407] invoke default property mechanism (ClassMagic)

[6408] return if anything but ST_NOT_FOUND

[6409] if array element property (‘bp->namep’ starts with ‘[’)

[6410] if extracting id value between the ‘[’ and ‘]’ successful:

[6411] convert the string value between ‘[’ and ‘]’ to element id

[6412] strip the ‘[xxx]’ and, if present, the ‘.’ after that

[6413] use element id calculated above and redirect to the Part ArrayAPI

[6414] else if broadcast property (name starts with “[*]”)

[6415] find virtual property with name the string after the “[*]”

[6416] if no such property exists, return St_NOT_FOUND

[6417] invoke same operation to the so found virtual property

[6418] redirect operation to the virtual property distributor

[6419] else return ST_NOT_FOUND

[6420] if ‘bp->namep’ is ‘._repeated’

[6421] ask virtual terminal container to find terminal with name equalto the property value.

[6422] if ST_OK (found) return ST_DUPLICATE

[6423] if ST_NOT_FOUND return ST_OK

[6424] else return status of the above operation

[6425] find virtual property with the same name as the requested by theoperation

[6426] if no such property exists, return ST_OK

[6427] invoke same operation on virtual property mechanism

[6428] redirect to property distributor

[6429] get_info

[6430] in: bp->namep—property name/id

[6431] (bp->hdl)—property handle (if ‘bp->namep’ is NULL)

[6432] out: bp->type—property type

[6433] bp->attr—property attributes

[6434] act: get information about specified property

[6435] s: St_NOT_FOUND—property name not found

[6436] nb: the information returned by this operation is not affected bythe current value of the property

[6437] if ‘bp->namep’ starts with ‘[’

[6438] if extracting id value between the ‘[’ and ‘]’ successful:

[6439] redirect the operation to Part Array stripping the ‘[ . . . ]’and, if present, the ‘.’ after that.

[6440] else if property name starts with “[*]”

[6441] find virtual property with name the string after the “[*]”

[6442] if no such property exists, return ST_NOT_FOUND

[6443] redirect operation to the virtual property

[6444] else return ST_NOT_FOUND

[6445] if ‘bp->namep’ is ‘._repeated’

[6446] return ST_NOT_SUPPORTED

[6447] find virtual property with the same name as the requested by theoperation

[6448] if no such property, return ST_NOT_FOUND

[6449] redirect operation to virtual property mechanism

[6450] qry_open

[6451] in: bp->namep—query string

[6452] bp->qry_mask—attributes to filter on query operations

[6453] bp->attr—values of attributes

[6454] out: bp->qry_ctx—query context for subsequent qry_xxx operations

[6455] act: open query on property namespace

[6456] s: ST_NO_ROOM—too many open queries

[6457] ST_BAD_SYNTAX—bad query syntax

[6458] return ST_BAD_SYNTAX if query is not “*”

[6459] allocate query instance:

[6460] allocate PROP_QRY instance on behalf of the host

[6461] open query on our properties

[6462] initialize query instance

[6463] state

[6464] query attribute mask

[6465] query attribute values

[6466] array.enum_ctx

[6467] associate query instance with a handle

[6468] pass

[6469] query handle as ‘bp->qry_ctx’

[6470] return ST_OK

[6471] qry_get_first

[6472] in: bp->namep—buffer for property name

[6473] bp->name_sz—size of buffer (bytes)

[6474] bp->qry_ctx—query context from prp_qry_open

[6475] out: bp->namep—property name

[6476] act: get first matching property name

[6477] s: ST_NOT_FOUND—no matching properties

[6478] ST_INVALID—bad query context

[6479] ST_OVERFLOW—buffer too small for property name

[6480] lock the query handle to resolve the query context

[6481] invoke pq_sm_feed (RESET, query context) [cleanup: unlock handle]

[6482] invoke pq_sm_feed (NEXT , query context) [cleanup: unlock handle]

[6483] unlock the handle

[6484] return ST_OK

[6485] qry_get_last

[6486] in: bp->namep—buffer for property name

[6487] bp->name_sz—size of buffer (bytes)

[6488] bp->qry_ctx—query context from prp_qry_open

[6489] out: bp->namep—property name

[6490] act: get last matching property name

[6491] s: St_NOT_FOUND—no matching properties

[6492] ST_INVALID—bad query context

[6493] ST_OVERFLOW—buffer too small for property name

[6494] return ST_NOT_SUPPORTED

[6495] qry_get_next

[6496] in: bp->namep—buffer for property name

[6497] bp->name_sz—size of buffer (bytes)

[6498] bp->qry_ctx—query context from prp_qry_open

[6499] out: bp->namep—property name

[6500] act: get next matching property name

[6501] s: ST_NOT_FOUND—no matching properties

[6502] ST_INVALID—bad query context

[6503] ST_OVERFLOW—buffer too small for property name

[6504] lock the query handle to resolve the query context

[6505] invoke pq_sm_feed (NEXT, query context) [cleanup: unlock handle]

[6506] unlock the handle

[6507] return ST_OK

[6508] qry_get_prev

[6509] in: bp->namep—buffer for property name

[6510] bp->name_sz—size of buffer (bytes)

[6511] bp->qry_ctx—query context from prp_qry_open

[6512] out: bp->namep—property name

[6513] act: get previous matching property name

[6514] s: ST_NOT_FOUND—no matching properties

[6515] ST_INVALID—bad query context

[6516] ST_OVERFLOW—buffer too small for property name

[6517] return ST_NOT_SUPPORTED

[6518] qry_get_curr

[6519] in: bp->namep—buffer for property name

[6520] bp->name_sz—size of buffer (bytes)

[6521] bp->qry_ctx—query context from prp_qry_open

[6522] out: bp->namep—property name

[6523] act: get current property name

[6524] s: ST_NOT_FOUND—no matching properties

[6525] ST_INVALID—bad query context

[6526] ST_OVERFLOW—buffer too small for property name

[6527] lock the query handle to resolve the query context

[6528] invoke pq_sm_feed (CURR, query context) [cleanup: unlock handle]

[6529] unlock the handle

[6530] return ST_OK

[6531] qry_close

[6532] in: bp->qry_ctx—query context for subsequent qry_xxx operations

[6533] out: void

[6534] act: close query on property namespace

[6535] s: ST_INVALID—bad query context

[6536] lock the query handle to resolve the query context

[6537] invoke pq_sm_feed (RESET, query context) [cleanup: unlock handle]

[6538] free query context

[6539] destroy the handle locked

[6540] return ST_OK

[6541] Private: Internal Methods

[6542] term_name_replace

[6543] in: sp—part self pointer

[6544] srcp—source terminal bus

[6545] tgtp—target terminal bus

[6546] bufp—storage

[6547] buf_sz—storage size

[6548] backward—TRUE to map old names to new names, FALSE otherwise

[6549] out: *tgtp—name replaced bus

[6550] act: replace name of the terminal with respective property

[6551] s: St_NOT_FOUND—no replacement happened

[6552] valchk: everything!=0

[6553] cmp_valp:=backward?‘._fact’: ‘sp->_fact’

[6554] rpl_valp:=backward?‘sp->_fact’: ‘._fact’

[6555] if cmp_valp matches with the name in ‘srcp->namep’

[6556] replace the ‘tgtp->namep’ with ‘bufp’

[6557] string copy ‘rpl_valp’ into ‘bufp’

[6558] return ST_OK

[6559] cmp_valp:=backward?‘._prop’: ‘sp->_prop’

[6560] rpl_valp:=backward?‘sp->_prop’: ‘._prop’

[6561] if cmp_valp matches with the name in ‘srcp->namep’

[6562] replace the ‘tgtp->namep’ with ‘bufp’

[6563] string copy ‘rpl valp’ into ‘bufp’

[6564] return ST_OK

[6565] cmp_valp:=backward?‘._conn’: ‘sp->_conn’

[6566] rpl_valp:=backward?‘sp->_conn’: ‘._conn’

[6567] if cmp_valp matches with the name in ‘srcp->namep’

[6568] replace the ‘tgtp->namep’ with ‘bufp’

[6569] string copy ‘rpl_valp’ into ‘bufp’

[6570] return ST_OK

[6571] return St_NOT_FOUND

[6572] pq_sm_feed

[6573] in: sp—property query instance data

[6574] selfp—part instance pointer

[6575] ev—event

[6576] bp—property bus pointer

[6577] out: *tgtp—name replaced bus

[6578] act: resolve and invoke action handler based on <state, event>0pair

[6579] s: <action handler status>

[6580] valchk: everything!=0

[6581] dispatch by event

[6582] compute action handler based on state

[6583] redirect to action handler

[6584] Private: Action Handlers for Property Enumeration State Machine

[6585] ah_reset

[6586] in: sp—property query state

[6587] sp->state—current state

[6588] selfp—part instance data

[6589] bp—property bus

[6590] out: *sp—modified query state

[6591] act: reset enumeration on array properties

[6592] s: ST_OK—success

[6593] (any other)—intermittent error

[6594] switch by sp->state

[6595] case S_PQ_ARRAY

[6596] close property query on us

[6597] zero sp->array portion of the query state

[6598] case S_PQ_VPROP

[6599] zero sp->vprop portion of the query state

[6600] case S_PQ_SUBS

[6601] close property query on subordinates

[6602] zero sp->subs portion of the query state

[6603] sp->state→S_PQ_ARRAY

[6604] return ST_OK

[6605] ah_arr_next

[6606] in: sp—property query state

[6607] sp->state—current state

[6608] selfp—part instance data

[6609] bp—property bus

[6610] out: *sp—modified query state

[6611] act: get next array property

[6612] s: ST_OK—success

[6613] (any other)—intermittent error

[6614] get first if array.enum_ctx==NO_CTX

[6615] open property query on us

[6616] use sp->attr_val, sp->attr_mask

[6617] get first

[6618] if ST_NOT_FOUND

[6619] close query on us

[6620] transit state to S_PQ_VPROP

[6621] initiziize vprop portion of the query state

[6622] re-feed the event

[6623] update state

[6624] return ST_OK

[6625] invoke get_next operation on us

[6626] update state (array.enum_ctx)

[6627] pass enum_ctx→bp->qry_ctx

[6628] return ST_OK

[6629] ah_arr_curr

[6630] in: sp—property query state

[6631] sp->state—current state

[6632] selfp—part instance data

[6633] bp—property bus

[6634] out: *sp—modified query state

[6635] act: get current array property

[6636] s: ST_OK—success

[6637] (any other)—intermittent error

[6638] invoke get_curr operation on us

[6639] return ST_OK

[6640] ah_vp_next

[6641] in: sp—property query state

[6642] sp->state—current state

[6643] selfp—part instance data

[6644] bp—property bus

[6645] out: *sp—modified query state

[6646] act: get next virtual property

[6647] s: ST_OK—success

[6648] (any other)—intermittent error

[6649] calculate which operation on the virtual property container tocall:

[6650] vprop.enum_ctx==NO_CTX?vc_get_first: vc_get_next

[6651] call operation

[6652] if St_NOT_FOUND

[6653] zero out vprop portion of the query state

[6654] transit state to S_PQ_SUBS

[6655] zero out subs portion of the query state

[6656] re-feed event

[6657] return ST_OK

[6658] pass if bp->namep!=NULL

[6659] return ST_OK

[6660] ah_vp_curr

[6661] in: sp—property query state

[6662] sp->state—current state

[6663] selfp—part instance data

[6664] bp—property bus

[6665] out: *sp—new query state

[6666] act: get current virtual property

[6667] s: ST_OK—success

[6668] (any other)—intermittent error

[6669] get current virtual property [if_ret]

[6670] pass if bp->namep!=NULL

[6671] return ST_OK

[6672] ah_subs_next

[6673] in: sp—property query state

[6674] sp->state—current state

[6675] selfp—part instance data

[6676] bp—property bus

[6677] out: *sp—new query state

[6678] act: get next property from the subordinates

[6679] s: ST_OK—success

[6680] (any other)—intermittent error

[6681] get first subordinate if subs.enum_ctx==NO_CTX

[6682] reset subordinates enumeration

[6683] get next subordinate

[6684] retrieve object ID

[6685] open query on subordinate

[6686] use sp->attr_mask, sp->attr_val

[6687] update subs state

[6688] enum_ctx:=subordinate enumeration

[6689] curr_oid:=current sub. object ID

[6690] curr_qryh:=property query handle

[6691] curr_(—)1st:=TRUE

[6692] recurse

[6693] get first/next property on current subordinate based onsp->subs.curr_(—)1^(st)

[6694] if ST_NOT_FOUND

[6695] close property query on current subordinate

[6696] get next subordinate [if_ret]

[6697] resolve its object ID

[6698] open query on new subordinate

[6699] use sp->attr_mask, sp->attr_val

[6700] update subs state

[6701] enum_ctx:=subordinate enumeration

[6702] curr_oid:=current sub. object ID

[6703] curr_qryh:=property query handle

[6704] curr_(—)1st:=FALSE

[6705] recurse

[6706] set sp->subs.curr_(—)1st to FALSE

[6707] return ST_OK

[6708] ah_subs_curr

[6709] in: sp—property query state

[6710] sp->state—current state

[6711] selfp—part instance data

[6712] bp—property bus

[6713] out: *sp—new query state

[6714] act: get current property from the subordinates

[6715] s: ST_OK—success

[6716] (any other)—intermittent error

[6717] return ST_NOT_FOUND if sp->subs.curr_(—)1st is TRUE

[6718] get current property on current subordinate based onsp->subs.curr_(—)1^(st) [if_ret]

[6719] return ST_OK

Appendix 6. VECON—Virtual Entity Container

[6720] The virtual entity container is used for holding the set ofvirtual properties and for holding the set of virtual terminals. typedefstruct VECON { _hdl owner_key; // owner key of the handle set CM_OIDoid; // memory owner uint32 off; // offset of name pointer } VECON;

[6721] This structure is the instance data of a container for virtualentities.

[6722] The virtual entity container helper maintains a set of handlesassociated with an owner. The owner is kept on the owner_key field.

[6723] The oid field is used for ownership of the memory allocated bythe helper. The memory allocation is performed on behalf of this object.

[6724] The off field is used to calculate the pointer to the name ofparticular entity by a base pointer supplied on all entity operations.

[6725] 1. Self Data Structure

[6726] The self is the VECON structure defined above.

Pseudo-code

[6727] 2. Virtual Entity Container

[6728] vc_construct

[6729] in: sp—storage for virtual terminal container instance

[6730] sz—size of the storage

[6731] oid—object to allocate on behalf on

[6732] off—offset of the pointer to the entity name

[6733] out: *sp—virtual entity container instance

[6734] act: construct virtual entity container container

[6735] s: ST_ALLOC—not enough memory

[6736] valchk: sp !=NULL

[6737] sanity chk: sz>=sizeof (VTCON)

[6738] create unique onwer key→sp->owner_key

[6739] off→sp->off

[6740] return ST_OK

[6741] vc_destruct

[6742] in: sp—virtual entity container instance

[6743] out: *sp—zeroed memory

[6744] act: destruct virtual entity container container

[6745] valchk: sp !=NULL

[6746] enumerate all handles that belong to sp->owner_key, for each

[6747] destroy handle

[6748] zero self

[6749] return ST_OK

[6750] vc_add

[6751] in: sp—virtual entity container instance ep—virtual entityinstance

[6752] out: void

[6753] act: add virtual entity to the container instance

[6754] s: ST_ALLOC—not enough memory

[6755] ST_NO_ROOM—too many virtual entities

[6756] ST_DUPLICATE—virtual entity with this name exists

[6757] valchk: sp !=NULL, vtp!=NULL

[6758] calc name pointer in the entity to add

[6759] enumerate handle set using sp->owner_key

[6760] lock handle, retrieve entity base pointer

[6761] calc name pointer in the contained entity

[6762] compare two names, if match

[6763] unlock handle

[6764] return ST_DUPLICATE

[6765] unlock handle

[6766] create handle:

[6767] owner: sp->owner_key

[6768] context: vtp

[6769] return ST_OK

[6770] vc_remove

[6771] in: sp—virtual entity container instance

[6772] ep—virtual entity to remove

[6773] out: void

[6774] act: remove virtual entity from the container instance

[6775] s: St_NOT_FOUND

[6776] calc name pointer of the entity to remove

[6777] enumerate all handles with onwer sp->key, for each

[6778] lock handle, retrieve entity base pointer

[6779] calc contained entity name pointer

[6780] compare two names, if match

[6781] destroy handle (locked)

[6782] return ST_OK

[6783] unlock handle

[6784] return ST_NOT_FOUND

[6785] vc_find

[6786] in: sp—virtual entity container instance

[6787] nmp—virtual terminal name to find

[6788] epp—storage for virtual entity instance ID

[6789] out: *epp—virtual entity instance ID

[6790] act: find virtual entity by name

[6791] s: St_NOT_FOUND—no such terminal

[6792] enumerate all handles with onwer sp->key, for each

[6793] lock handle, retrieve entity base pointer

[6794] calc contained entity name pointer

[6795] if name of entity is the same as nmp (string compare)

[6796] pass entity base pinter→*epp

[6797] unlock handle

[6798] return ST_OK

[6799] unlock handle

[6800] return St_NOT_FOUND

[6801] vc_get_first

[6802] in: sp—virtual entity container instance

[6803] ep—storage for virtual entity instance ID or NULL

[6804] enum_ctxp—storage for enumeration context

[6805] out: *enum_ctxp—enumeration context

[6806] (*epp)—virtual entity instance ID (if ‘epp’ is not NULL)

[6807] act: get first virtual terminal

[6808] s: ST_NOT_FOUND—no terminals

[6809] get first handle with onwer sp->owner_key [if_ret]

[6810] lock handle, retrieve entity base pointer, unlock handle

[6811] pass entity base pointer>*epp

[6812] pass enum_ctx→*enum_ctxp

[6813] return ST_OK

[6814] vc_get_next

[6815] in: sp—virtual entity container instance

[6816] epp—storage for virtual entity instance ID or NULL

[6817] enum_ctxp—pointer to enumeration context from previous vc_get_xxxoperation

[6818] out: *enum_ctxp—new enumeration context

[6819] (*epp)—virtual entity instance ID (if ‘epp’ is not NULL)

[6820] act: get next virtual terminal according to the enumerationcontext

[6821] s: ST_NOT_FOUND—no more terminals

[6822] get next handle with owner sp->owner_key [if_ret]and enumerationcontext: *enum_ctxp

[6823] lock handle, retrieve entity base pointer , unlock handle

[6824] pass entity base pointer→*epp

[6825] pass enum_ctx→*enum_ctxp

[6826] return ST_OK

[6827] vc_get_curr

[6828] in: sp—virtual terminal container instance

[6829] epp—storage for virtual entity instance ID or NULL

[6830] enum_ctx—enumeration context from previous vc_get_xxx operation

[6831] out:(*epp)—virtual entity instance ID (if ‘epp’ is not NULL)

[6832] act: get current virtual terminal according to the enumerationcontext

[6833] s: St_NOT_FOUND—no current terminal

[6834] return ST_NOT_SUPPORTED

Appendix 7. VPROP—Virtual Property Helper

[6835] The virtual property helper uses the following structure tomaintain the data associated with a single instance of a virtualproperty. typedef struct VPROP { char *namep; // name of the propertyuint16 type; // property data type void *valp; // pointer to valueuint32 len; // length of the value CM_OID oid; // object to allocate onbehalf of } VPROP;

[6836] The name of the property is kept by reference; the helper isresponsible to allocate the storage. The same is valid for the value ofthe property. The name/value storage allocation happens at the same timewhen the virtual property is added (created) and therefore has the samelife scope as the property itself.

[6837] The reason for this storage being allocated dynamically is thatthere is no explicit limit on the length of the property name. The sameis valid for the property value.

[6838] 1. Self Data Structure

[6839] The self is the VPROP structure defined above.

Pseudo-code

[6840] vp_construct

[6841] in: sp—storage for virtual property instance

[6842] sz—size of the storage

[6843] oid—object to allocate on behalf on

[6844] nmp—property name

[6845] out: *sp—virtual property instance

[6846] act: construct virtual property instance

[6847] s: ST_ALLOC—not enough memory

[6848] valchk: sp !=NULL, nmp!=NULL

[6849] sanity chk: sz>=sizeof VPROP

[6850] allocate memory for the property name on behalf of oid [if_ret]

[6851] sz=strlen (nmp)+1

[6852] copy name into allocated memory

[6853] zero *sp out

[6854] update sp

[6855] allocated memory→sp->namep

[6856] oid→sp->oid

[6857] PROP_T_NONE→sp->type

[6858] 0→sp->len

[6859] NULL→sp->valp

[6860] return ST_OK

[6861] vp_destruct

[6862] in: sp—virtual property instance

[6863] out: *sp—zeroed memory

[6864] act: destruct virtual property instance

[6865] valchk: sp !=NULL

[6866] free sp->namep on behalf of sp->oid

[6867] if sp->valp not NULL free sp->valp on behalf of sp->oid

[6868] return ST_OK

[6869] vp_get

[6870] in: sp—virtual property instance

[6871] bp->type—expected value type or PROP_T_NONE for any

[6872] bp->p—buffer for property value or NULL

[6873] (bp->sz)—size of buffer (if bp->p!=NULL)

[6874] out: bp->type—actual type of value (if bp->type==PROP_T_NONE)

[6875] (*bp->p)—property value (if bp->p!NULL)

[6876] bp->len—actual length of value, [bytes], incl. any terminators

[6877] act: get virtual property value

[6878] s: ST_REFUSE—incorrect property type

[6879] ST_OVERFLOW—buffer too small for property value

[6880] nb: bp->sz must be provided for all property types, includedfixed-size

[6881] valchk: sp !=NULL, bp !=NULL

[6882] if bp->p is NULL

[6883] pass

[6884] sp->len→bp->len

[6885] return ST_OK

[6886] if bp->sz<sp->len return ST_OVERFLOW

[6887] pass

[6888] sp->type→bp->type

[6889] copy sp->valp to bp->p (len: sp->len)

[6890] sp->len→bp->len

[6891] return ST_OK

[6892] vp_set

[6893] in: sp—virtual property instance

[6894] bp->type—property type or PROP_T_NONE if unknown

[6895] bp->p—buffer containing property value, NULL for default

[6896] bp->len—actual length of value, [bytes], or 0 for auto

[6897] out: void

[6898] act: set virtual property value

[6899] s: ST_REFUSE—incorrect property type

[6900] ST_BAD_VALUE—bad property value

[6901] ST_OVERFLOW—property value too long

[6902] nb: bp->len==0 is allowed only on fixed-size types, ASCIZ andUNICODEZ

[6903] valchk: sp !NULL, bp !=NULL

[6904] if bp->p is NULL return ST_OK

[6905] bp->len→len

[6906] recalc value length if len is 0

[6907] SINT32, UINT32: len=4

[6908] ASCIZ: fen=strlen (bp->p)+1

[6909] MBCSZ: len=mbclen (bp->p)+1

[6910] UNICODE: len=wclen (bp->p)+2;

[6911] any other: return ST_INVALID

[6912] if sp->len<len

[6913] reallocate valp to len on behalf of sp->oid

[6914] copy bp->p to sp->len

[6915] len→sp->len

[6916] return ST_OK

[6917] vp_chk

[6918] in: sp—virtual property instance

[6919] bp->namep—name of property to check or NULL

[6920] bp->type—property type or PROP_T_NONE if unknown

[6921] bp->p—buffer containing property value, NULL for default

[6922] bp->ten—actual length of value, [bytes], or 0 for auto

[6923] out: void

[6924] act: check virtual property value

[6925] s: ST_REFUSE—incorrect property type

[6926] ST_BAD_VALUE—bad property value

[6927] ST_OVERFLOW—property value too long

[6928] nb: bp->len==0 is allowed only on fixed-size types, ASCIZ andUNICODEZ

[6929] valchk: sp !=NULL, bp !=NULL

[6930] return ST_OK

[6931] vp_get_info

[6932] in: sp—virtual property instance

[6933] bp->p—buffer for the name

[6934] bp->sz—size of the buffer

[6935] out: *bp->p—virtual property name

[6936] (bp->sz)—size of buffer needed for property name (if ST_OVERFLOWreturned)

[6937] bp->type—property type

[6938] act: retrieve information about the virtual property

[6939] s: ST_OVERFLOW—buffer too small (bp->sz contains the needed size)

[6940] valchk: sp !=NULL, bp !=NULL

[6941] strlen (sp->namep)+1→len

[6942] if len>bp->sz

[6943] pass

[6944] bp->sz=len

[6945] return ST_OVERFLOW

[6946] pass

[6947] copy string sp->namep→bp->p

[6948] sp->type→bp->type

[6949] return ST_OK

Appendix 8. VPDST—Virtual Property Distributor

[6950] The following structure is the instance data of a distributor ofvirtual property values. typedef struct VPDST { DM_ARR_HDR *arrp; //array instance CM_OID oid; // object to allocate memory on behalf of }VPDST;

[6951] The arrp field is used to identify the Part Array instance asprovided by ClassMagic.

[6952] The oid field is used for ownership of the memory allocated bythe helper. The memory allocation is performed on behalf of this object.

[6953] 1. Self Data Structure

[6954] The self is the VPDST_structure defined above.

Pseudo-code

[6955] vpd_construct

[6956] in: sp—storage for virtual property distributor instance

[6957] sz—size of the storage

[6958] oid—object ID to allocate on behalf of

[6959] arrp—array instance ID to distribute to

[6960] out: *sp—virtual property distributor instance

[6961] act: construct virtual property distributor instance

[6962] s: ST_ALLOC—not enough memory

[6963] valchk: sp !=NULL

[6964] sanity chk: sz>=sizeof (VPDST)

[6965] arrp→sp->arrp

[6966] oid→sp->oid

[6967] return ST_OK

[6968] vpd_destruct

[6969] in: sp—virtual property distributor instance

[6970] out: *sp—zeroed memory

[6971] act: destruct virtual property distributor instance

[6972] valchk: sp !=NULL

[6973] zero out *sp

[6974] return ST_OK

[6975] vpd_set

[6976] in: sp—virtual property distributor instance

[6977] bp->p—pointer to value to set (NULL for default)

[6978] bp->len—value length (0—for auto)

[6979] bp->type—property type or PROP_T_NONE if unknown

[6980] skip_err—TRUE to skip errors

[6981] out: void

[6982] act: set virtual property value to all elements in the array

[6983] s: ST_REFUSE—incorrect property type

[6984] ST_BAD_VALUE—bad property value

[6985] ST_OVERFLOW—property value too long

[6986] nb: bp->len==0 is allowed only on fixed-size types, ASCIZ andUNICODEZ

[6987] valchk: sp !=NULL, bp !=NULL

[6988] nit ‘operation status’ to ST_OK

[6989] enum keys in the array, for each one

[6990] invoke DM_ARR_prp_set( ) using the value in the buffer and typefrom

[6991] ‘bp’

[6992] if skip_err continue enumeration

[6993] if error set it into ‘operation status’ and stop enumeration

[6994] return ‘operation status’

[6995] vpd_chk

[6996] in: sp—virtual property distributor instance

[6997] bp->p—pointer to value to check (NULL for default)

[6998] bp->len—value length (0—for auto)

[6999] bp->type—property type or PROP_T_NONE if unknown

[7000] out: void

[7001] act: check virtual property value to all elements in the array

[7002] s: ST_REFUSE—incorrect property type

[7003] ST_BAD_VALUE—bad property value

[7004] ST_OVERFLOW—property value too long

[7005] nb: bp->len==0 is allowed only on fixed-size types, ASCIZ andUNICODEZ

[7006] valchk: sp !=NULL, bp !=NULL

[7007] init ‘operation status’ to ST_OK

[7008] enum keys in the array, for each one

[7009] invoke DM_ARR_prp_chk( ) using the value in the buffer and typefrom ‘bp’

[7010] if error set it into ‘operation status’ and stop enumeration

[7011] return ‘operation status’

Appendix 9. VTERM—Virtual Terminal Helper

[7012] The following structure is the instance data of a single virtualterminal. typedef struct VTERM { char *namep; // pointer to terminalname bool connected; // TRUE if terminal connected byteconn_ctx[CONN_CTX_SZ]; // connection context char name[MAX_TERM_NM_SZ];// virtual terminal name word sync; // synchronicity dword attr; //terminal attributes } VTERM;

[7013] The instance data contains the name of the terminal (fixedlength), indication whether this terminal is connected and theconnection data (context), synchronicity and attributes supplied by thecounter terminal (if connected).

[7014] The virtual entity container utilizes the pointer to the virtualterminal name (namep field).

[7015] 1. Self Data Structure

[7016] The self is the VTERM structure defined above.

Pseudo-code

[7017] vt_construct

[7018] in: sp—storage for virtual terminal instance

[7019] sz—size of the storage

[7020] oid—object to allocate on behalf on

[7021] nmp—terminal name

[7022] out: *sp—virtual terminal instance

[7023] act: construct virtual terminal instance

[7024] s: ST_ALLOC—not enough memory

[7025] argchk: sp !=NULL, sz>=sizeof (VTERM), nmp!=NULL

[7026] if name (nmp) is too long return ST_OVERFLOW

[7027] copy terminal name into self (sp->name)

[7028] set sp->namep to point to sp->name

[7029] set sp->connected to FALSE

[7030] zero init the connection context (sp->conn_ctx)

[7031] set sp->attr and sp->sync to zero

[7032] return ST_OK

[7033] vt_destruct

[7034] in: sp—virtual terminal instance

[7035] out: *sp—zeroed memory

[7036] act: destruct virtual terminal instance

[7037] argchk: sp !=NULL

[7038] memset sp to zeros

[7039] return ST_OK

Appendix 10. VTRME—Virtual Terminal Mechanism (Exterior)

[7040] This mechanism is used to handle exterior virtual terminals.

[7041] 1. Structures Used

[7042] 1.1. VTERM—Virtual Terminal

[7043] This structure is the instance data of a single virtual terminal.typedef struct VTERM { char *namep; // pointer to terminal name boolconnected; // TRUE if terminal connected byte conn_ctx[CONN_CTX_SZ]; //connection context char name[MAX_TERM_NM_SZ]; // virtual terminal nameword sync; // synchronicity dword attr; // terminal attributes } VTERM;

[7044] The instance data contains the name of the terminal (fixedlength), indication whether this terminal is connected and theconnection data (context), synchronicity and attributes supplied by thecounter terminal (if connected).

[7045] The virtual entity container utilizes the pointer to the virtualterminal name (namep field).

[7046] 2. Self Data Structure

[7047] The self is the VTERM structure defined above.

Pseudo-code

[7048] vte_acquire

[7049] in: sp—virtual terminal instance

[7050] bp->conn_id—connection id or NO_ID

[7051] out: bp->context—connection context

[7052] bp->mech—terminal mechanism [TERM_M]

[7053] bp->card—cardinality

[7054] bp->sync—terminal synchronosity

[7055] bp->dir—terminal direction

[7056] bp->attr—terminal attributes

[7057] bp->conn_h—connection handle

[7058] act: acquire connection context

[7059] s: ST_NOT_FOUND—terminal not found

[7060] ST_REFUSE—component is in inappropriate state

[7061] ST_NO_ROOM—terminal cardinality exhausted

[7062] ST_OVERFLOW—provided space for context is not enough

[7063] argchk: sp !=NULL, bp !=NULL

[7064] if sp->connected return ST_NO_ROOM (cardinality exhausted)

[7065] prepare connection context:

[7066] tag=RDX_TRM_CTX_VTBL_TAG;

[7067] sz=sizeof (sp->conn_ctx)

[7068] cid_out=CID_ANY

[7069] pass:

[7070] connection context assembled above

[7071] bp->mech=TERM_M_VTABLE

[7072] bp->card=1

[7073] bp->sync=TERM_S_BOTH

[7074] bp->dir=TERM_D_OUTPUT

[7075] bp->attr=TERM_A_ACTIVETIME|TERM_A_NEGOTIABLE

[7076] bp->conn_h=NO_HDL

[7077] return ST_OK

[7078] vte_release

[7079] in: sp—virtual terminal instance

[7080] (bp->conn_id)—connection id or NO_ID

[7081] (bp->conn_h)—connection handle or NO_HDL

[7082] out: void

[7083] act: release connection context

[7084] s: ST_NO_ACTION—the specified context was not acquired

[7085] ST_REFUSE—component is in inappropriate state

[7086] ST_NOT_FOUND—terminal not found

[7087] nb: either ‘conn_id’ or ‘conn_h’ should contain a value for thisoperation to succeed; if both contain values, ‘conn_id’ is ignored.

[7088] argchk: sp !=NULL, bp !=NULL

[7089] return ST_OK

[7090] vte_connect

[7091] in: sp—virtual terminal instance

[7092] bp->mech—target terminal mechanism [TERM_M]

[7093] bp->sync—target terminal synchronosity

[7094] bp->dir—target terminal direction

[7095] bp->attr—target terminal attributes

[7096] bp->context—connection context of the terminal to connect to

[7097] (bp->conn_id)—connection id or NO_ID

[7098] (bp->conn_h)—connection handle or NO_HDL

[7099] out: void

[7100] act: connect terminal to another terminal

[7101] s: ST_REFUSE—interface mismatch (e.g., unacceptable‘contract_id’) or inappropriate state

[7102] ST_NOT_FOUND—terminal not found

[7103] ST_OVERFLOW—implementation imposed restriction in # ofconnections

[7104] nb: either ‘conn_id’ or ‘conn_h’ should contain a value for thisoperation to succeed; if both contain values, ‘conn_id’ is ignored.

[7105] nb: The connection context structures are ‘tagged’ , i.e. thefirst 8 bits contain an identifier of the structure. Any implementationmust check and recognize the ‘tag’ before it can operate with the restof the structure.

[7106] argchk: sp !=NULL, bp !=NULL

[7107] sanity check: if sp->connected return ST_REFUSE

[7108] verify connection is possible:

[7109] if bp->dir has an output return ST_REFUSE

[7110] if bp->mech not vtable return ST_REFUSE

[7111] if tag in bp->context!=RDX_TRM_CTX_VTBL_TAG return ST_REFUSE

[7112] copy connection data (bp->context) into sp->conn_ctx

[7113] set sp->sync to bp->sync

[7114] set sp->attr to bp->attr

[7115] set sp->connected to TRUE

[7116] return ST_OK

[7117] vte_disconnect

[7118] in: sp—virtual terminal instance

[7119] (bp->conn_id)—connection id or NO_ID

[7120] (bp->conn_h)—connection handle or NO_HDL

[7121] out: void

[7122] act: disconnect terminal

[7123] s: ST_REFUSE—component is in inappropriate state

[7124] nb: either ‘conn_id’ or ‘conn_h’ should contain a value for thisoperation to succeed; if both contain values, ‘conn_id’ is ignored.

[7125] argchk: sp !=NULL, bp !=NULL

[7126] if sp->connected is FALSE return ST_OK

[7127] zero out connection context (sp->conn_ctx)

[7128] set sp->connected to FALSE

[7129] return ST_OK

[7130] vte_get_info

[7131] in: sp—virtual terminal instance

[7132] out: bp->mech—terminal mechanism [TERM_M]

[7133] bp->card—terminal cardinality (static, not current)

[7134] bp->n_conn—current # of connections

[7135] bp->sync—terminal synchronosity

[7136] bp->attr—terminal attributes

[7137] bp->dir—terminal direction

[7138] act: return information about specified terminal

[7139] argchk: sp !=NULL, bp !=NULL

[7140] bp->mech=TERM_M_VTABLE

[7141] bp->card=1

[7142] bp->n_conn=(if sp->connected then 1 else 0)

[7143] bp->sync=TERM_S_BOTH

[7144] bp->dir=TERM_D_OUTPUT

[7145] bp->attr=TERM_A_ACTIVETIME|TERM_A_NEGOTIABLE

[7146] return ST_OK

Appendix 11. VTRMI—Virtual Terminal Mechanism (Interior)

[7147] This mechanism is used to handle exterior virtual terminals.

[7148] 1. Structures Used

[7149] 1.1. VTERM—Virtual Terminal typedef struct VTERM { char *namep;// pointer to terminal name bool connected; // TRUE if terminalconnected byte conn_ctx[CONN_CTX_SZ]; // connection context charname[MAX_TERM_NM_SZ]; // virtual terminal name word sync; //synchronocity dword attr; // terminal attributes } VTERM;

[7150] This structure is the instance data of a single virtual terminal.

[7151] The instance data contains the name of the terminal (fixedlength), indication whether this terminal is connected and theconnection data (context), synchronocity and attributes supplied by thecounter terminal (if connected).

[7152] The virtual entity container utilizes the pointer to the virtualterminal name (namep field).

[7153] 2. Self Data Structure

[7154] The self is the VTERM structure defined above.

Pseudo-code

[7155] vti_acquire

[7156] in: sp—virtual terminal instance

[7157] bp->conn_id—connection id or NO_ID

[7158] out: bp->context—connection context

[7159] bp->mech—terminal mechanism [TERM_M]

[7160] bp->card—cardinality

[7161] bp->sync—terminal synchronosity

[7162] bp->dir—terminal direction

[7163] bp->attr—terminal attributes

[7164] bp->conn_h—connection handle

[7165] act: acquire connection context

[7166] s: ST_NOT_FOUND—terminal not found

[7167] ST_NOT_CONNECTED—virtual terminal not connected

[7168] ST_REFUSE—component is in inappropriate state

[7169] ST_NO_ROOM—terminal cardinality exhausted

[7170] ST_OVERFLOW—provided space for context is not enough

[7171] argchk: sp !=NULL, bp !=NULL

[7172] if sp->connected is FALSE return ST_NOP

[7173] pass:

[7174] connection context in self (sp->conn_ctx)

[7175] bp->mech=TERM_M_VTABLE

[7176] bp->card=infinite

[7177] bp->sync=sp->sync

[7178] bp->dir=TERM_D_INPUT

[7179] bp->attr=sp->attr

[7180] bp->conn_h=NO_HDL

[7181] return ST_OK

[7182] vti_release

[7183] in: sp—virtual terminal instance

[7184] (bp->conn_id)—connection id or NO_ID

[7185] (bp->conn_h)—connection handle or NO_HDL

[7186] out: void

[7187] act: release connection context

[7188] s: ST_NO_ACTION—the specified context was not acquired

[7189] ST_REFUSE—component is in inappropriate state

[7190] ST_NOT_CONNECTED—virtual terminal not connected

[7191] ST_NOT_FOUND—terminal not found

[7192] nb: either ‘conn_id’ or ‘conn_h’ should contain a value for thisoperation to succeed; if both contain values, ‘conn_id’ is ignored.

[7193] argchk: sp !=NULL, bp !=NULL

[7194] if sp->connected is FALSE return ST_NOP

[7195] return ST_OK

[7196] vti_connect

[7197] in: sp—virtual terminal instance

[7198] bp->mech—target terminal mechanism [TERM_M]

[7199] bp->sync—target terminal synchronosity

[7200] bp->dir—target terminal direction

[7201] bp->attr—target terminal attributes

[7202] bp->context—connection context of the terminal to connect to

[7203] (bp->conn_id)—connection id or NO_ID

[7204] (bp->conn_h)—connection handle or NO_HDL

[7205] out: void

[7206] act: connect terminal to another terminal

[7207] s: ST_REFUSE—interface mismatch (e.g., unacceptable‘contract_id’) or inappropriate state

[7208] ST_NOT_FOUND—terminal not found

[7209] ST_NOT_CONNECTED—virtual terminal not connected

[7210] ST_OVERFLOW—implementation imposed restriction in # ofconnections

[7211] nb: either ‘conn_id’ or ‘conn_h’ should contain a value for thisoperation to succeed; if both contain values, ‘conn_id’ is ignored.

[7212] nb: The connection context structures are ‘tagged’, i.e. thefirst 8 bits contain an identifier of the structure. Any implementationmust check and recognize the ‘tag’ before it can operate with the restof the structure.

[7213] argchk: sp !=NULL, bp !=NULL

[7214] if sp->connected is FALSE return ST_NOP

[7215] verify connection is possible:

[7216] if bp->dir has an input return ST_REFUSE

[7217] if bp->mech not vtable return ST_REFUSE

[7218] if bp->sync and sp->sync are not compatable return ST_REFUSE

[7219] if target terminal tag!=RDX_TRM_CTX_VTBL_TAG return ST_REFUSE

[7220] set cid_any to TRUE if either the target terminal output cid isCIDANY or if sp->conn_ctx input cid is CID_ANY

[7221] if not cid_any and target terminal output cid !=sp->conn_ctxinput cid return ST_REFUSE

[7222] return ST_OK

[7223] vti_disconnect

[7224] in: sp—virtual terminal instance

[7225] (bp->conn_id)—connection id or NO_ID

[7226] (bp->conn_h)—connection handle or NO_HDL

[7227] out: void

[7228] act: disconnect terminal

[7229] s: ST_REFUSE—component is in inappropriate state

[7230] ST_NOT CONNECTED—virtual terminal not connected

[7231] nb: either ‘conn_id’ or ‘conn_h’ should contain a value for thisoperation to succeed; if both contain values, ‘conn_id’ is ignored.

[7232] argchk: sp !=NULL, bp !=NULL

[7233] if sp->connected is FALSE return ST_NOP

[7234] return ST_OK

[7235] vti_get_info

[7236] in: sp—virtual terminal instance

[7237] out: bp->mech—terminal mechanism [TERM_M]

[7238] bp->card—terminal cardinality (static, not current)

[7239] bp->n_conn—current # of connections

[7240] bp->sync—terminal synchronosity

[7241] bp->attr—terminal attributes

[7242] bp->dir—terminal direction

[7243] act: return information about specified terminal

[7244] argchk: sp !=NULL, bp !=NULL

[7245] bp->mech=TERM_M_VTABLE

[7246] bp->card=infinite

[7247] bp->n_conn=1

[7248] bp->sync sp->sync

[7249] bp->dir=TERM_D_INPUT

[7250] bp->attr=sp->attr

[7251] return ST_OK

Appendix 12. VTDST—Virtual Terminal Distributor

[7252] The following structure is the instance data of a distributor ofconnections to virtual terminals.

[7253] typedef struct VTDST

[7254] {

[7255] DM_ARR_HDR *arrp; //array instance ID

[7256] CM_OID oid; //object ID of the host

[7257] }VTDST;

[7258] The arrp field is used to identify the Part Array instance asprovided by ClassMagic.

[7259] The oid field is used for ownership of the memory allocated bythe helper. The memory allocation is performed on behalf of this object.

[7260] 1. Self Data Structure

[7261] The self is the VTDST structure defined above.

Pseudo-code

[7262] vtd_construct

[7263] in: sp—storage for virtual terminal distributor instance

[7264] sz—size of the storage

[7265] oid—host

[7266] arrp—array instance ID to distribute to

[7267] out: *Sp—virtual terminal distributor instance

[7268] act: construct virtual terminal distributor instance

[7269] s: ST_ALLOC—not enough memory

[7270] valchk: sp !=NULL

[7271] sanity chk: sz>=sizeof (VTDST)

[7272] arrp→sp->arrp

[7273] oid→sp->oid

[7274] return ST_OK

[7275] vtd_destruct

[7276] in: sp—virtual terminal distributor instance

[7277] out: *sp—zeroed memory

[7278] act: destruct virtual terminal distributor instance

[7279] valchk: sp !=NULL

[7280] zero out *sp

[7281] return ST_OK

[7282] vtd_connect

[7283] in: sp—virtual terminal distributor instance

[7284] bp->namep—terminal name

[7285] skip_err—TRUE to skip all errors

[7286] out: void

[7287] act: connect the virtual terminal to all array elements

[7288] nb: ‘skip_err’ will skip real errors only; if a terminal name isnot found on a particular part this will not be considered as an errorand the part will be skipped independently of whether ‘skip_err’ is TRUEor FALSE

[7289] valchk: sp !=NULL, bp !=NULL

[7290] enumerate keys in the array, for each key

[7291] invoke DM_ARR_connect_oid

[7292] sp->arrp

[7293] key from enumeration

[7294] bp->namep (terminal name on the array element)

[7295] sp->oid

[7296] bp->namep (terminal name on the other side)

[7297] key from enumeration (as conn_id)

[7298] if skip_err continue enumeration

[7299] if status different than ST_OK, St_NOT_FOUND, return it

[7300] return ST_OK

[7301] vtd_disconnect

[7302] in: sp—virtual terminal distributor instance

[7303] bp->namep—terminal name

[7304] out: void

[7305] act: disconnect the virtual terminal from all array elements

[7306] valchk: sp !=NULL, bp !=NULL

[7307] enumerate keys in the array, for each key

[7308] invoke DM_ARR_connect_oid

[7309] sp->arrp

[7310] key from enumeration

[7311] bp->namep (terminal name on the array element)

[7312] sp->oid

[7313] bp->namep (terminal name on the other side)

[7314] key from enumeration (as conn_id)

[7315] return ST_OK

Appendix 13. Interfaces Used by Described Mechanisms

[7316] /* ------------------------------------------------------- *//*    ARR - Part Array    */ /* */ /*    VECON.H - Virtual EntityContainer Interface    */ /*------------------------------------------------------- */ /* Copyright(c) 1998 Object Dynamics Corp. All Rights Reserved. */ /* */ /* Use ofcopyright notice does not imply publication or disclosure. */ /* THISSOFTWARE CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION */ /*CONSTITUTING VALUABLE TRADE SECRETS OF OBJECT DYNAMICS CORP., AND */ /*MAY NOT BE (a) DISCLOSED TO THIRD PARTIES, (b) COPIED  IN ANY FORM, *//* OR (c) USED FOR ANY PURPOSE EXCEPT AS SPECIFICALLY  PERMITTED IN *//* WRITING BY OBJECT DYNAMICS CORP. */ /*------------------------------------------------------- */#ifndef_VECON_H_(—) #define_VECON_H_(—) /* --- Definitions------------------------------- */ // instance data (the impl. detailwill be hidden) typedef struct VECON { _hdl owner_key; // owner key ofthe handle set CM_OID oid; // memory owner uint32 off; // offset of namepointer } VECON; // factory _fpi_vc_construct (VECON *sp, uint32 sz,CM_OID oid, uint32 off); _fpi_vc_destruct (VECON *sp); // container_fpi_vc_add (VECON *sp, void *ep); _fpi_vc_remove (VECON *sp, void *ep);_fpi_vc_find (VECON *sp, const char *nmp, void **epp); // enumeration_fpi_vc_get_first (VECON *sp, void **epp, _ctx *ctxp); _fpi_vc_get_next(VECON *sp, void **epp, _ctx *ctxp); _fpi_vc_get_curr (VECON *sp, void**epp, _ctx ctx); /* --- Descriptions ------------------------------- */// on : vc_construct // in : sp - storage for virtual entity containerinstance // sz - size of the storage // oid - object to allocate onbehalf of // off - offset of the entity name pointer // out: *sp -virtual entity container instance // act: construct virtual entitycontainer instance // s : ST_ALLOC - not enough memory // on :vc_destruct // in : sp - virtual entity container instance // out: *sp -zeroed memory // act: destruct virtual entity container instance // on :vc_add // in : sp - virtual entity container instance // ep - virtualentity instance // out: void // act: add virtual entity to the containerinstance // s : ST_ALLOC - not enough memory // ST_NO_ROOM - too manyvirtual properties // ST_DUPLICATE - duplicate entity name // on :vc_remove // in : sp - virtual entity container instance // ep - virtualentity to remove // out: void // act: remove virtual entity from thecontainer instance // s : ST_NOT_FOUND // on : vc_find // in : sp -virtual entity container instance // nmp - virtual entity name to find// epp - storage for virtual entity // out: *epp - virtual entity //act: find virtual entity by name // s : ST_NOT_FOUND - no such property// on : vc_get_first // in : sp - virtual entity container instance //epp - storage for virtual entity or NULL // enum_ctxp - storage forenumeration context // out: *enum_ctxp - enumeration context // (*epp) -virtual entity (if ‘epp’ is not NULL) // act: get first virtual entity// s : ST_NOT_FOUND - no terminals // on : vc_get_next // in : sp -virtual entity container instance // epp - storage for virtual entity orNULL // enum_ctxp - pointer to enumeration context from previous //vc_get_xxx operation // out: *enum_ctxp - new enumeration context //(*epp) - virtual entity (if ‘epp’ is not NULL) // act: get next virtualentity according to the enumeration context // s : ST_NOT_FOUND - nomore terminals // on : vc_get_curr // in : sp - virtual entity containerinstance // epp - storage for virtual entity or NULL // enum_ctx -enumeration context from previous vc_get_xxx  operation // out:(*epp) -virtual entity (if ‘epp’ is not NULL) // act: get current virtual entityaccording to the enumeration context // s : ST_NOT_FOUND - no currentterminal #endif // _VECON_H_

[7317] /* ------------------------------------------------------- *//*    ARR - Part Array    */ /* */ /*  VPROP.H - Virtual PropertyMechanism Helper Interface  */ /*------------------------------------------------------- */ /* Copyright(c) 1998 Object Dynamics Corp. All Rights Reserved. */ /* */ /* Use ofcopyright notice does not imply publication or disclosure. */ /* THISSOFTWARE CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION */ /*CONSTITUTING VALUABLE TRADE SECRETS OF OBJECT DYNAMICS CORP., AND */ /*MAY NOT BE (a) DISCLOSED TO THIRD PARTIES, (b) COPIED  IN ANY FORM, *//* OR (c) USED FOR ANY PURPOSE EXCEPT AS SPECIFICALLY  PERMITTED IN *//* WRITING BY OBJECT DYNAMICS CORP. */ /*------------------------------------------------------- */#ifndef_VPROP_H_(—) #define_VPROP_H_(—) /* --- Definitions------------------------------- */ // instance data (the impl. detailwill be hidden) typedef struct VPROP { char *namep; // name of theproperty uint16 type; // property data type void *valp; // pointer tovalue uint32 len; // length of the value CM_OID oid; // memory owner }VPROP; typedef struct B_VPROP { void *p; // data pointer uint32 len; //length uint32 sz; // size uint type; // property type } B_VPROP; /* ---Operations ------------------------------- */ // factory_fpi_vp_construct (VPROP *sp, uint32 sz, CM_OID oid, const char *nmp);_fpi_vp_destruct (VPROP *sp); // mechanism operations _fpi_vp_get (VPROP*sp, B_VPROP *bp); _fpi_vp_set (VPROP *sp, B_VPROP *bp); _fpi_vp_chk(VPROP *sp, B_VPROP *bp); // utility _fpi_vp_get_info (VPROP *sp,B_VPROP *bp); /* --- Descriptions ------------------------------- */ //on : vp_construct // in : sp - storage for virtual property instance //sz - size of the storage // oid - object to allocate on behalf on //nmp - property name // out: *sp - virtual property instance // act:construct virtual property instance // s : ST_ALLOC - not enough memory// on : vp_destruct // in : sp - virtual property instance // out: *sp -zeroed memory // act: destruct virtual property instance // on : vp_get// in : sp - virtual property instance // bp->type - expected value typeor PROP_T_NONE for any // bp->p - buffer for property value or NULL //(bp->sz) - size of buffer (if bp->p != NULL) // out: bp->type - actualtype of value (if bp->type == PROP_T_NONE) // (*bp->p) - property value(if bp->p != NULL) // bp->len - actual length of value, [bytes], incl.any terminators // act: get virtual property value // s : ST_REFUSE -incorrect property type // ST_OVERFLOW - buffer too small for propertyvalue // nb : bp->sz must be provided for all property types, includedfixed-size // on : vp_set // in : sp - virtual property instance //bp->type - property type or PROP_T_NONE if unknown // bp->p - buffercontaining property value, NULL for default // bp->len - actual lengthof value, [bytes], or 0 for auto // out: void // act: set virtualproperty value // s : ST_REFUSE - incorrect property type //ST_BAD_VALUE - bad property value // ST_OVERFLOW - property value toolong // nb : bp->len == 0 is allowed only on fixed-size types, ASCIZ andUNICODEZ // on : vp_chk // in : sp - virtual property instance //bp->namep - name of property to check or NULL // bp->type - propertytype or PROP_T_NONE if unknown // bp->p - buffer containing propertyvalue, NULL for default // bp->len - actual length of value, [bytes], or0 for auto // out: void // act: check virtual property value // s :ST_REFUSE - incorrect property type // ST_BAD_VALUE - bad property value// ST_OVERFLOW - property value too long // nb : bp->len == 0 is allowedonly on fixed-size types, ASCIZ and UNICODEZ // on : vp_get_info // in :sp - virtual property instance // bp->p - buffer for the name //bp->sz - size of the buffer // out: *bp->p - virtual property name //(bp->sz) - size of buffer needed for property name // (if ST_OVERFLOWreturned) // bp->type - property type // act: retrieve information aboutthe virtual property // s : ST_OVERFLOW - buffer too small (bp->szcontains the needed size) #endif // _VPROP_H_(—)

[7318] /* ------------------------------------------------ */ /* ARR -Part Array */ /* ------------------------------------------------ *//*   VPDST.H - Virtual Property Distributor Helper Interface   */ /*------------------------------------------------ */ /* Copyright (c)1998 Object Dynamics Corp. All Rights Reserved.   */ /* */ /* Use ofcopyright notice does not imply publication or disclosure.   */ /* THISSOFTWARE CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION   */ /*CONSTITUTING VALUABLE TRADE SECRETS OF OBJECT DYNAMICS CORP., AND    *//* MAY NOT BE (a) DISCLOSED TO THIRD PARTIES, (b) COPIED IN ANY FORM, *//* OR (c) USED FOR ANY PURPOSE EXCEPT AS SPECIFICALLY PERMITTED IN */ /*WRITING BY OBJECT DYNAMICS CORP. */ /*------------------------------------------------ */ #ifndef_VPDST_H_(—)#define_VPDST_H_(—) /* --- Definitions-------------------------------------- */ // instance data (the impl.detail will be hidden) typedef struct VPDST { DM_ARR_HDR *arrp; // arrayinstance ID CM_OID  oid; // object to allocate memory on behalf of }VPDST; /* -- Operations ---------------------------------------- */ //factory _fpi_vpd_construct (VPDST *sp, uint32 sz, CM_OID oid, _hdlarrh); _fpi_vpd_destruct (VPDST *sp); // operations _fpi_vpd_set (VPDST*sp B_PROPERTY *bp, bool skip_err); _fpi_vpd_chk (VPDST *sp B_PROPERTY*bp); /* --- Descriptions ------------------------------------------- */// on vpd_construct // in : sp - storage for virtual propertydistributor instance // sz - size of the storage // oid - object ID toallocate on behalf of // arrp - array instance ID to distribute to //out: *sp - virtual property distributor instance // act: constructvirtual property distributor instance // s : ST_ALLOC - not enoughmemory // on : vpd_destruct // in : sp - virtual property distributorinstance // out: *sp - zeroed memory // act: destruct virtual propertydistributor instance // on vpd_set // in : sp - virtual propertydistributor instance // bp −> p - pointer to value to set (NULL fordefault) // bp −> len - value length (0 - for auto) // bp −> type -property type or PROP_T_NONE if unknown // skip_err - TRUE to skiperrors // out: void // act: set virtual property value to all elementsin the array // s : ST_REFUSE - incorrect property type//  ST_BAD_VALUE - bad property value //  ST_OVERFLOW - property valuetoo long // nb : bp −>len == 0 is allowed only on fixed-size types,ASCIZ and UNICODEZ // nb : ‘skip_err’ will skip real errors only; if aproperty name is not found //  on a particular part this will not beconsidered as an error and //  the part will be skipped independently ofwhether ‘skip err’ is //  TRUE or FALSE // on   vpd_chk // in sp -virtual property distributor instance //  vp - virtual property todistribute the value of // out: void // act: check virtual propertyvalue to all elements in the array // s : ST_REFUSE - incorrect propertytype //  ST_BAD_VALUE - bad property value //   ST_OVERFLOW - propertyvalue too long // nb : bp−>len == 0 is allowed only on fixed-size types,ASCIZ and UNICODEZ #endif // _VPDST_H_

[7319] /* ------------------------------------------------ */ /* ARR -Part Array */ /* ------------------------------------------------ *//*   VTERM.H - Virtual Terminal Helper Interface   */ /*------------------------------------------------ */ /* Copyright (c)1998 Object Dynamics Corp. All Rights Reserved.   */ /* */ /* Use ofcopyright notice does not imply publication or disclosure.   */ /* THISSOFTWARE CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION   */ /*CONSTITUTING VALUABLE TRADE SECRETS OF OBJECT DYNAMICS CORP., AND    *//* MAY NOT BE (a) DISCLOSED TO THIRD PARTIES, (b) COPIED IN ANY FORM, *//* OR (c) USED FOR ANY PURPOSE EXCEPT AS SPECIFICALLY PERMITTED IN */ /*WRITING BY OBJECT DYNAMICS CORP. */ /*------------------------------------------------ */ #ifndef _VTERM_H_(—)#define _VTERM_H_(—) /* --- Definitions-------------------------------------- */ // instance data (the impl.detail will be hidden) typedef struct VTERM { char *namep; // pointer toentity name bool connected; // TRUE if terminal is connected byteconn_ctx[TERM_CONN_CTX_SZ]; // connection context charname[RDX_MAX_TRM_NM_LEN + 1]; // virtual terminal name } VTERM; /* ---Operations --------------------------------------*/ // factory_fpi_vt_construct (VTERM *sp, uint32 sz, CM_OID_oid, const char *nmp);_fpi_vt_destruct (VTERM *sp); /* --- Operations---------------------------------------*/ // on vt_construct // in :sp - storage for virtual terminal instance // sz - size of the storage// oid - object to allocate on behalf on // nmp - terminal name // out:*sp - virtual terminal instance // act: construct virtual terminalinstance // s : ST_ALLOC - not enough memory // on : vt_destruct // in :sp - virtual terminal instance // out: *sp - zeroed memory // act:destruct virtual terminal instance #endif // VTERM_H_(—)

[7320] /* ------------------------------------------------ */ /* ARR -Part Array */ /* ------------------------------------------------ *//*   VTRME.H - Exterior Virtual Terminal Helper Interface   */ /*------------------------------------------------ */ /* Copyright (c)1998 Object Dynamics Corp. All Rights Reserved.   */ /* */ /* Use ofcopyright notice does not imply publication or disclosure.   */ /* THISSOFTWARE CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION   */ /*CONSTITUTING VALUABLE TRADE SECRETS OF OBJECT DYNAMICS CORP., AND    *//* MAY NOT BE (a) DISCLOSED TO THIRD PARTIES, (b) COPIED IN ANY FORM, *//* OR (c) USED FOR ANY PURPOSE EXCEPT AS SPECIFICALLY PERMITTED IN */ /*WRITING BY OBJECT DYNAMICS CORP. */ /*------------------------------------------------ */ #ifndef _VTRME_H_(—)#define _VTRME_H_(—) /* --- Definitions --------------------------------*/ #include <vterm.h> /* --- Operations--------------------------------- */ // mechanism operations_fpi_vte_acquire (VTERM *sp, B_TERMINAL *bp); _fpi_vte_connect (VTERM*sp, B_TERMINAL *bp); _fpi_vte_disconnect (VTERM *sp, B_TERMINAL *bp);_fpi_vte_release (VTERM *sp, B_TERMINAL *bp); // utility_fpi_vte_get_info (VTERM *sp, B_TERMINAL *bp); /* --- Descriptions-------------------------------- */ // on : vte_acquire // in : sp -virtual terminal instance // bp −> conn_id - connection id or NO_ID //out: bp −> context - connection context // bp −> type - terminal type[TERM_TYPE] // bp −> card - cardinality // bp −> sync - terminalsynchronosity // bp −> dir - terminal direction // bp −> attr - terminalattributes // bp −> conn_h - connection handle // act: acquireconnection context // s : ST_NOT_FOUND - terminal not found //ST_REFUSE - component is in inappropriate state // ST_NO_ROOM - terminalcardinality exhausted // ST_OVERFLOW - provided space for context is notenough // on : vte_release // in : sp - virtual terminal instance // (bp−> conn_id) - connection id or NO_ID // (bp −> conn_h) - connectionhandle or NO_HDL // out: void // act: release connection context // s :ST_NO_ACTION - the specified context was not acquired // ST_REFUSE -component is in inappropriate state // ST_NOT_FOUND - terminal not found// nb : either ‘conn_id’ or ‘conn_h’ should contain a value for thisoperation //  to succeed; if both contain values, ‘conn id’ is ignored.// on : vte_connect // in : sp - virtual terminal instance // bp −>type - target terminal type [TERM_TYPE] // bp −> sync - target terminalsynchronosity // bp −> dir - target terminal direction // bp −> attr -target terminal attributes // bp −> context - connection context of theterminal to connect to // (bp −> conn_id) - connection id or NO_ID //(bp −> conn_h) - connection handle or NO_HDL // out: void // act:connect terminal to another terminal // s : ST_REFUSE -interfacemismatch (e.g., unacceptable ‘contract_id’) // or inappropriate state//ST_NOT_FOUND - terminal not found //ST_OVERFLOW - implementationimposed restriction in # of connections // nb : either ‘conn id’ or‘conn_h’ should contain a value for this operation //  to succeed; ifboth contain values, ‘conn id’ is ignored. // nb : The connectioncontext structures are ‘tagged’ , i.e. the first //  8 bits contain anidentifier of the structure. Any implementation must //  check andrecognize the ‘tag’ before it can operate with the rest of //  thestructure. // on : vte_disconnect // in : sp - virtual terminal instance// (bp −> conn_id) - connection id or NO_ID // (bp −> conn_h) -connection handle or NO_HDL // out: void // act: disconnect terminal //s : ST_REFUSE   - component is in inappropriate state // nb : either‘conn_id’ or ‘conn_h should contain a value for this operation //  tosucceed; if both contain values, ‘conn id’ is ignored. // on :vte_get_info // in : sp - virtual terminal instance // out: bp −> type -terminal type [TERM_TYPE] // bp −> card - terminal cardinality (static,not current) // bp −> n_conn - current # of connections // bp −> sync -terminal synchronosity // bp −> attr - terminal attributes // bp −>dir - terminal direction // act: return information about specifiedterminal #endif // VTRME_H_(—)

[7321] /* ------------------------------------------------ */ /* ARR -Part Array */ /* ------------------------------------------------ *//*   VTRMI.H - Interior Virtual Terminal Helper Interface   */ /*------------------------------------------------ */ /* Copyright (c)1998 Object Dynamics Corp. All Rights Reserved.   */ /* */ /* Use ofcopyright notice does not imply publication or disclosure.   */ /* THISSOFTWARE CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION   */ /*CONSTITUTING VALUABLE TRADE SECRETS OF OBJECT DYNAMICS CORP., AND    *//* MAY NOT BE (a) DISCLOSED TO THIRD PARTIES, (b) COPIED IN ANY FORM, *//* OR (c) USED FOR ANY PURPOSE EXCEPT AS SPECIFICALLY PERMITTED IN */ /*WRITING BY OBJECT DYNAMICS CORP. */ /*------------------------------------------------ */ #ifndef _VTRMI_H_(—)#define _VTRMI_H_(—) /* --- Definitions --------------------------------*/ #include <vterm.h> /* --- Operations--------------------------------- */ // mechanism operations_fpi_vti_acquire (VTERM *sp, B_TERMINAL *bp); _fpi_vti_connect (VTERM*sp, B_TERMINAL *bp); _fpi_vti_disconnect (VTERM *sp, B_TERMINAL *bp);_fpi_vti_release (VTERM *sp, B_TERMINAL *bp); // utility_fpi_vti_get_info (VTERM *sp B_TERMINAL *bp); /* --- Descriptions---------------------------------*/ // on : vti_acquire // in : sp -virtual terminal instance // bp −> conn_id - connection id or NO_ID //out: bp −> context - connection context // bp −> type - terminal type[TERM_TYPE] // bp −> card - cardinality // bp −> sync - terminalsynchronosity // bp −> dir - terminal direction // bp −> attr - terminalattributes // bp −> conn_h - connection handle // act: acquireconnection context // s : ST_REFUSE - component is in inappropriatestate // ST_NO_ROOM - terminal cardinality exhausted // ST_NOP -operation cannot be performed at this time // ST_OVERFLOW - providedspace for context is not enough // on : vti_release // in : sp - virtualterminal instance // (bp −> conn_id) - connection id or NO_ID // (bp −>conn_h) - connection handle or NO_HDL // out: void // act: releaseconnection context // s : ST NO_ACTION - the specified context was notacquired // ST_NOT_CONNECTED - virtual terminal not connected //ST_REFUSE - component is in inappropriate state // nb : either ‘conn_id’ or ‘conn_h’ should contain a value for this operation //  to succeed;if both contain values, ‘conn_id’ is ignored. // on : vti_connect // in: sp - virtual terminal instance // bp −> type - target terminal type[TERM TYPE] // bp −> sync - target terminal synchronosity // bp −> dir -target terminal direction // bp −> attr - target terminal attributes //bp −> context - connection context of the terminal to connect to // (bp−> conn_id) - connection id or NO_ID // (bp −> conn_h) - connectionhandle or NO_HDL // out: void // act: connect terminal to anotherterminal // s : ST_REFUSE - interface mismatch (e.g., unacceptable //‘contract_id’) or inappropriate state // ST_OVERFLOW - implementationimposed restriction in # of // connections // ST_NOP - operation cannotbe performed at this time // nb : either ‘conn_id’ or ‘conn_h’ shouldcontain a value for this operation //  to succeed; if both containvalues, ‘conn_id’ is ignored. // nb : The connection context structuresare ‘tagged’ , i.e. the first //  8 bits contain an identifier of thestructure. Any implementation must //  check and recognize the ‘tag’before it can operate with the rest of //  the structure. // on :vti_disconnect // in : sp - virtual terminal instance // (bp −>conn_id) - connection id or NO_ID // (bp −> conn_h) - connection handleor NO_HDL // out: void // act: disconnect terminal // s : ST_REFUSE -component is in inappropriate state // ST_NOP - operation cannot beperformed at this time // nb : either ‘conn_id’ or ‘conn_h’ shouldcontain a value for this operation //  to succeed; if both containvalues, ‘conn_id’ is ignored. // on : vti_get_info // in : sp - virtualterminal instance // out: bp −> type - terminal type [TERM_TYPE] // bp−> card - terminal cardinality (static, not current) // bp −> n_conn -current # of connections // bp −> sync - terminal synchronosity // bp −>attr - terminal attributes // bp −> dir - terminal direction // act:return information about specified terminal // s : ST_NOP - operationcannot be performed at this time #endif // _VTRMI_H_(—)

[7322] /* ------------------------------------------------ */ /* ARR -Part Array */ /* ------------------------------------------------ *//*   VTDST.H - Virtual Terminal Distributor Helper Interface   */ /*------------------------------------------------ */ /* Copyright (c)1998 Object Dynamics Corp. All Rights Reserved.   */ /* */ /* Use ofcopyright notice does not imply publication or disclosure.   */ /* THISSOFTWARE CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION   */ /*CONSTITUTING VALUABLE TRADE SECRETS OF OBJECT DYNAMICS CORP., AND    *//* MAY NOT BE (a) DISCLOSED TO THIRD PARTIES, (b) COPIED IN ANY FORM, *//* OR (c) USED FOR ANY PURPOSE EXCEPT AS SPECIFICALLY PERMITTED IN */ /*WRITING BY OBJECT DYNAMICS CORP. */ /*------------------------------------------------ */ #ifndef _VTDST_H_(—)#define _VTDST_H_(—) /* --- Definitions --------------------------------*/ // instance data (the impl. detail will be hidden) typedef structVTDST { DM_ARR_HDR *arrp; // array instance ID CM_OID  oid; // object IDof the host } VTDST; /* --- Operations -------------------------------*/// factory _fpi_vtd_construct (VTDST *sp, uint32 sz, CM_OID oid, _hdlarrh); _fpi_vtd_destruct (VTDST *sp); // operations _fpi_vtd_connect(VTDST *sp, B_TERMINAL *vtp, bool skip_err); _fpi_vtd_disconnect (VTDST*sp, B_TERMINAL *vtp); /* --- Descriptions------------------------------------ */ // on : vtd_construct // in :sp - storage for virtual terminal distributor instance // sz - size ofthe storage // oid - host // arrp - array instance ID to distribute to// out: *sp - virtual terminal distributor instance // act: constructvirtual terminal distributor instance // s : ST_ALLOC  - not enoughmemory // on : vtd_destruct // in : sp - virtual terminal distributorinstance // out: *sp - zeroed memory // act: destruct virtual terminaldistributor instance // on vtd_connect // in : sp - virtual terminaldistributor instance // bp −> namep - terminal name // skip_err - TRUEto skip all errors // out: void // act: connect the terminal on the hostto all array elements // nb : ‘skip_err’ will skip real errors only; ifa terminal name is not found //  on a particular part this will not beconsidered as an error and //  the part will be skipped independently ofwhether ‘skip_err’ is //  TRUE or FALSE // on vtd_disconnect // in :sp - virtual terminal distributor instance // bp −> namep - terminalname // out: void // act: disconnect the terminal on the host from allarray elements #endif // _VTDST_H_(—)

Appendix 14. Interfaces Exposed by DM_ARR

[7323] This sections describes the interfaces used by the DM_ARRterminals fact, prop and conn. These interfaces are I_A_FACT, I_A_PROPand I_A_CONN, respectively. /*------------------------------------------------ */ /* I_A_FACT.H -Array Factory */ /* */ /* Copyright (c) 1990-1998 Object Dynamics Corp.All Rights Reserved.   */ /*------------------------------------------------ */ /*BE180BD0-D30B-11D1-B589-0040052479F6 /*------------------------------------------------ */#ifndef_I_A_FACT_H_(—) #define_I_A_FACT_H_(—) // attribute definitions#define A_FACT_A_NONE   0 #define A_FACT_A_USE_ID   (1UL << 0) // busdeclaration BUS (B_A_FACT) fig32 attr ; // attributes [A_FACT_A_XXX]char *namep ; // class name for part to create uint32 id ; // partinstance id ctx ctx ; // enumeration context END_BUS // interfacedeclaration IFACE (I_A_FACT, (CM_USRBASE + Ox1640)) oper (create ,B_A_FACT) oper (destroy , B_A_FACT) oper (activate , B_A_FACT) oper(deactivate , B_A_FACT) oper (get first , B_A_FACT) oper (get next ,B_A_FACT) END_IFACE // Operation descriptions: // on create // in :attr - attributes [A_FACT_A_XXX] // namep - class name of part or NULLfor default // id -id to use if A_FACT_A_USE_ID is set // out: id - idof the created part (A_FACT_A_USE_ID is clear) // act: Create a partinstance in the array // s : CMST_OK - successful // CMST_CANT_BIND -the part class was not found // CMST_ALLOC - not enough memory //CMST_NO_ROOM - no more parts can be created // CMST_DUPLICATE - thespecified id already exists (if A_FACT_A_USE_ID) // (all others) -specific error occurred during object creation // on destroy // in :id - id of part to destroy // out: void // act: destroy a part instancein the array // s : CMST_OK - successful // CMST_NOT_FOUND - a part withthe specified id was not found //  (all others) - an intermittent erroroccurred during destruction // on activate // in : id - id of part toactivate // out: void // act: activate a part instance in the array // s: CMST OK - successful // CMST_NOT_FOUND - a part with the specified idwas not found // CMST_NO_ACTION - the object is already active //CMST_REFUSE - mandatory properties have not been set or // terminals notconnected // (all others) - as returned by part's activator //on deactivate // in : id - id of part to deactivate // out: void // act:deactivate a part instance in the array // s : CMST_OK - successful //CMST_NOT_FOUND - a part with the specified id was not found // (allothers) - as returned by part's deactivator // on  get_first // in :void // out: id - id of the first part in the array // ctx enumerationcontext for subsequent get_next // act: get the first part in the partarray // s : CMST_OK - successful // CMST_NOT_FOUND - the array has noparts // on get_next // in : ctx - enumeration context from previousget_xxx // out: id - id of next part in the array // ctx - enumerationcontext for subsequent get_xxx // act: get the next part in the partarray // s : CMST_OK - successful // CMST_NOT_FOUND - the array has nomore parts #endif // _I_A_FACT_H_(—)

[7324] /*----------------------------------------------------------------- */ /*    I_A_PROP.H - Array Property   1 */ /* */ /* Copyright (c) 1990-1998Object Dynamics Corp. All Rights Reserved. */ /*--------------------------------------------------------------------------*/ /* BE180BD3-D30B-11D1-B589-0040052479F6 */ /*--------------------------------------------------------------------------*/ #ifndef_I_A_PROP_H_(—) #define_I_A_PROP_H_(—) // bus declaration BUS(B_A_PROP) uint32 id; // id of the instance that is the operation targetchar *namep; // property name [ASCIZ] uint16 type; // property type[CMPRP_T_XXX] flg32 attr; // attributes [CMPRP_A_XXX] flg32 attr_mask;// attribute mask for queries [CMPRP_A_XXX] void *bufp; // pointer toinput buffer uint32 buf_sz; // size of *bufp in bytes uint32 val_len; //length of value in *bufp in bytes _hdl qryh; // query handle END_BUS //interface declaration IFACE (I_A_PROP, (CM_USRBASE + 0x1650)) oper (get , B_A_PROP) oper (get  , B_A_PROP) oper (chk, B_A_PROP) oper (get_info,B_A_PROP) oper (qry_open, B_A_PROP) oper (qry_close, B_A_PROP) oper(qry_first, B_A_PROP) oper (qry_next, B_A_PROP) oper (qry_curr,B_A_PROP) END_IFACE // Operation descriptions: // on  get //in:id -target instance ID // namep - null-terminated property name // type -type of the property to retrieve // or CMPRP_T_NONE for any // bufp -pointer to buffer to receive property or NULL // buf_sz - size in bytesof *bufp // out:*bufp) - property value // val_len - length in bytes ofproperty value // act: get the value of a property from a part in thearray // s : CMST_OK - successful // CMST_NOT_FOUND - the property couldnot be found or the id is invalid // CMST_REFUSE - the data type doesnot match the expected type // CMST_OVERFLOW - the buffer is too smallto hold the property value // on set // in:id - target instance ID //namep - null-terminated property name // type - type of the property toset // bufp - pointer to buffer containing property value // val_len -size in bytes of property value // out:void // act:set the value of aproperty of a part in the array If s:CMST_OK - successful //CMST_NOT_FOUND - the property could not be found // or the id is invalid// CMST_REFUSE - the property type is incorrect or the property //cannot be changed while the part is in an active // state //CMST_OUT_OF_RANGE - the property value is not within the range of //allowed values for this property // CMST BAD ACCESS - there has been anattempt to set a // read-only property // CMST_OVERFLOW - the propertyvalue is too large // CMST_NULL_PTR - the property name pointer is NULLor an attempt was // made to set default value for a property that does// not have a default value // nb: for string properties, val_len mustinclude the terminating zero // nb: If bufp is NULL, the function triesto reset the property value to If its default. // on chk //in : id -target instance ID // namep - null-terminated property name // type -type of the property value to check // bufp - pointer to buffercontaining property value // val_len - size in bytes of property value// out: void // act: check if a property can be set to the specifiedvalue // s : CMST_OK - successful // CMST_NOT_FOUND - the property couldnot be found or the id // is invalid // CMST_REFUSE - the property typeis incorrect or the property // cannot be changed while the part is inan active // state // CMST_OUT_OF_RANGE - the property value is notwithin the range of // allowed values for this property //CMST_BAD_ACCESS - there has been an attempt to set a // read-onlyproperty // CMST_OVERFLOW - the property value is too large //CMST_NULL_PTR - the property name pointer is NULL or an attempt was //made to set default value for a property that does // not have a defaultvalue // on get_info // in:id - target instance ID // namep -null-terminated property name // out:type - type of property[CMPRP_T_XXX] // attr - property attributes [CMPRP_A_XXX] // act:retrieve the type and attributes of the specified property // s :CMST_OK - successful // CMST_NOT_FOUND - the property could not be found// or the id is invalid // on qry_open // in : id - target instance ID// namep - query string (must be “*”) // attr - attribute values ofproperties to include // attr mask - attribute mask of properties toinclude // out: qryh - query handle // act: open a query to enumerateproperties on a part in the array based // upon the specified attributemask and values // or CMPRP_A_NONE to enumerate all properties // s :CMST_OK - successful // CMST_NOT_FOUND - the Id could not be found or isinvalid // CMST_NOT_SUPPORTED - the specified part does not supportproperty // enumeration or does not support nested or // concurrentproperty enumeration // nb : To filter by atrributes, specifiy the setof attributes in attr_mask // and their desired values in attr. Duringthe enumeration, a bit-wise // AND is performed between the actualattributes of each property and // the value of attr_mask; the result isthen compared to attr. If there // is an exact match, the property willbe enumerated. // nb : To enumerate all properties of a part, specifiythe query string as “*”, // and attr_mask and attr as 0. // nb : Theattribute mask can be one or more of the following: // CMPRP_A_NONE -not specified // CMPRP_A_PERSIST - persistent property //CMPRP_A_ACTIVETIME - property can be modified while active //CMPRP_A_MANDATORY - property must be set before activation //CMPRP_A_RDONLY - read-only property // CMPRP_A_UPCASE - force uppercase// CMPRP_A_ARRAY - property is an array // on qry close // in: qryh //out: void // act: close a query // s : CMST_OK - successful //CMST_NOT_FOUND - query handle was not found or is invalid // CMST_BUSY -the object can not be entered from this execution // context at thistime. // on qry_first //in : qryh - query handle returned on qry_open //bufp - storage for the returned property name or NULL // buf_sz - sizein bytes of *bufp // out:(*bufp) - property name (if bufp not NULL) //act: retrieve the first property in a query // s : CMST_OK - successful// CMST_NOT_FOUND - no properties found matching current query //CMST_OVERFLOW - buffer is too small for property name // on qry_next//in : qryh - query handle returned on qry open // bufp - storage forthe returned property name or NULL // buf_sz - size in bytes of *bufp//out:(*bufp) - property name (if bufp not NULL) // act: retrieve thenext property in a query // s : CMST_OK - successful // CMST_NOT_FOUND -there are no more properties that match the // query criteria // CMSTOVERFLOW - buffer is too small for property name // on qry_curr // in :qryh - query handJe returned on qry_open // bufp - storage for thereturned property name // buf_sz - size in bytes of *bufp //out:(*bufp) - property name (if bufp not NULL) // act: retrieve thecurrent property in a query // s : CMST_OK - successful //CMST_NOT_FOUND - no current property (e.g. after a call to qry_open) //CMST_OVERFLOW - buffer is too small for property name #endif //_I_A_PROP_H

[7325] /*--------------------------------------------------------------------------*/ /* I_A_CONN.H - Array Connection */ /* */ /* Copyright ©1990-1998Object Dynamics Corp. All Rights Reserved. */ /*--------------------------------------------------------------------------*/ /* BE180BD4-D30B-11D1-B589-0040052479F6 */ /*--------------------------------------------------------------------------*/ #ifndef_I_A_CONN_H #define_I_A_CONN_H // bus declaration BUS(B_A_CONN) uint32 id1 ; // array element id or oid of part 1 char*term1_namep ; // terminal name of part 1 uint32 id2 ; // array elementid or oid of part 2 char *term2_namep ; // terminal name of part 2 _idconn_id ; // connection id END_BUS // interface declaration IFACE(I_A_CONN, (CM USRBASE + 0 × 1660)) oper (connect_ , B_A_CONN) oper(disconnect , B_A_CONN) END_IFACE // Operation descriptions: // onconnect_ // in : id1 - id or oid of part 1 // term1_namep - terminalname of part 1 // id2 - id or oid of part 2 // term2_namep - terminalname of part 2 // conn_id - connection id to represent this connection// out: void // act: connect two terminals between parts in the array orbetween a part in // the array and a part outside of the array // s :CMST_OK - successful // CMST_REFUSE - there has been an interface ordirection mismatch // or an attempt has been made to connect anon-active- // time terminal when the part is in an active state //CMST_NOT_FOUND - at least one of the terminals could not be found or //one of the ids is invalid // CMST_OVERFLOW - an implementation imposedrestriction in the number // of connections has been exceeded // nb :the operation name, connect_, has a trailing underscore to avoid // nameconflict with the connect macro used in the CONNECTIONS table. // nb :id1 and id2 may be the same to connect two terminals on the same part //nb : at least one of the two ids must be an id of a part in the array //nb : if the part specified by oid is the array host, its terminal namemay // identify an interior or exterior terminal. In all other cases,only // exterior terminals can be connected. // on disconnect // in :id1 - id or oid of part 1 // term 1_namep - terminal name of part 1 //id2 - id or oid of part 2 // term2_namep - terminal name of part 2 //conn_id - connection id to represent this connection // out: void //act: disconnect specified terminals // s : CMST_OK - successful //(other) - intermittent failure; if possible, the connection // has beendissolved // nb : see notes above on part ids and terminal names #endif// _I_A_CONN_H_

Glossary

[7326] The following definitions will assist the reader in comprehendingthe enclosed description of a preferred embodiment of the presentinvention. All of the following definitions are presented as they applyin the context of the present invention.

[7327] Adapter a part which converts one interface, logical connectioncontract and/or physical connection mechanism to another. Adapters areused to establish connections between parts that cannot be connecteddirectly because of incompatibilities.

[7328] Alias an alternative name or path representing a part, terminalor property. Aliases are used primarily to provide alternativeidentification of an entity, usually encapsulating the exact structureof the original name or path.

[7329] Assembly a composite object most of the functionality of which isprovided by a contained structure of interconnected parts. In many casesassemblies can be instantiated by descriptor and do not require specificprogram code.

[7330] Bind or binding an operation of resolving a name of an entity toa pointer, handle or other identifier that can be used to access thisentity. For example, a component factory provides a bind operation thatgives access to the factory interface of an individual component classby a name associated with it.

[7331] Bus, part a part which provides a many-to-many type ofinteraction between other parts. The name “bus” comes from the analogywith network architectures such as Ethernet that are based on a commonbus through which every computer can access all other computers on thenetwork.

[7332] Code, automatically generated program code, such as functions orparts of functions, the source code for which is generated by a computerprogram.

[7333] Code, general purpose program code, such as functions andlibraries, used by or on more than one class of objects.

[7334] COM an abbreviation of Component Object Model, a component modeldefined and supported by Microsoft Corp. COM is the basis of OLE2technologies and is supported on all members of the Windows family ofoperating systems.

[7335] Component an instantiable object class or an instance of suchclass that can be manipulated by general purpose code using onlyinformation available at run-time. A Microsoft COM object is acomponent, a Win32 window is a component; a C++ class without run-timetype information (RTTI) is not a component.

[7336] Component model(s) a class of object model based onlanguage-independent definition of objects, their attributes andmechanisms of invocation. Unlike object-oriented languages, componentmodels promote modularity by allowing systems to be built from objectsthat reside in different executable modules, processes and computers.

[7337] Connecting process of establishing a connection between terminalsof two parts in which sufficient information is exchanged between theparts to establish that both parts can interact and to allow at leastone of the parts to invoke services of the other part.

[7338] Connection an association between two terminals for the purposesof transferring data, invoking operations or passing events.

[7339] Connection broker an entity that drives and enforces theprocedure for establishing connections between terminals. Connectionbrokers are used in the present invention to create connectionsexchanging the minimum necessary information between the objects beingconnected.

[7340] Connection, direction of a characteristic of a connection definedby the flow of control on it. Connections can be unidirectional, such aswhen only one of the participants invokes operations on the other, orbidirectional, when each of the participants can invoke operations onthe other one.

[7341] Connection, direction of data flow a characteristic of aconnection defined by the data flow on it. For example, a function callon which arguments are passed into the function but no data is returnedhas unidirectional data flow as opposed to a function in which somearguments are passed in and some are returned to the caller .

[7342] Connection, logical contract a defined protocol of interaction ona connection recognized by more than one object. The same logicalcontract may be implemented using different physical mechanisms.

[7343] Connection, physical mechanism a generic mechanism of invokingoperations and passing data through connections. Examples of physicalmechanisms include function calls, messages, v-table interfaces, RPCmechanisms, inter-process communication mechanisms, network sessions,etc.

[7344] Connection point see terminal.

[7345] Connection,

[7346] synchronosity a characteristic of a connection which defineswhether the entity that invokes an operation is required to wait untilthe execution of the operation is completed. If at least one of theoperations defined by the logical contract of the connection must besynchronous, the connection is assumed to be synchronous.

[7347] Container an object which contains other objects. A containerusually provides interfaces through which the collection of multipleobjects that it contains can be manipulated from outside.

[7348] Control block see Data bus.

[7349] CORBA Common Object Request Broker Architecture, a componentmodel architecture maintained by Object Management Group, Inc., aconsortium of many software vendors.

[7350] Critical section a mechanism, object or part the function ofwhich is to prevent concurrent invocations of the same entity. Used toprotect data integrity within entities and avoid complications inherentto multiple threads of control in preemptive systems.

[7351] Data bus a data structure containing all fields necessary toinvoke all operations of a given interface and receive back results fromthem. Data buses improve understandability of interfaces and promotepolymorphism. In particular interfaces based on data buses are easier tode-synchronize, convert, etc.

[7352] Data flow direction in which data is being transferred through afunction call, message, interface or connection. The directions areusually denoted as “in”, “out” or “in-out”, the latter defining abidirectional data flow.

[7353] Descriptor table an initialized data structure that can be usedto describe or to direct a process. Descriptors are especially useful inconjunction with general purpose program code. Using properly designeddescriptor tables, such code can be directed to perform differentfunctions in a flexible way .

[7354] De-serialization part of a persistency mechanism in objectsystems. A process of restoring the state of one or more objects from apersistent storage such as file, database, etc. See also serialization.

[7355] De-synchronizer a category of parts used to convert synchronousoperations to asynchronous. Generally, any interface with unidirectionaldata flow coinciding with the flow of control can be de-synchronizedusing such a part.

[7356] Event in the context of a specific part or object, any invocationof an operation implemented by it or its subordinate parts or objects.Event-driven designs model objects as state machines which change stateor perform actions in response to external events. In the context of asystem of objects, a notification or request typically not directed to asingle object but rather multicast to, or passed through, a structure ofobjects. In a context of a system in general, an occurrence.

[7357] Event, external An event caused by reasons or originated outsideof the scope of a given system.

[7358] Execution context State of a processor and, possibly of regionsof memory and of system software, which is not shared between streams ofprocessor instructions that execute in parallel. Typically includes somebut not necessarily all processor registers, a stack, and, inmultithreaded operating systems, the attributes of the specific thread,such as priority, security, etc.

[7359] Factory, abstract a pattern and mechanism for creating instancesof objects under the control of general purpose code. The mechanism usedby OLE COM to create object instances is an abstract factory; theoperator ‘new’ in C++ is not an abstract factory .

[7360] Factory, component or part portion of the program code of acomponent or part which handles creation and destruction of instances.Usually invoked by an external abstract factory in response torequest(s) to create or destroy instances of the given class.

[7361] Flow of control a sequence of nested function calls, operationinvocations, synchronous messages, etc. Despite all abstractions ofobject-oriented and event-driven methods, on single-processor computersystems the actual execution happens strictly in the sequence of theflow of control.

[7362] Group property a property used to represent a set of otherproperties for the purposes of their simultaneous manipulation. Forexample, an assembly containing several parts may define a groupproperty through which similar properties of those parts can be set fromoutside via a single operation.

[7363] Indicator a category of parts that provides human-readablerepresentation of the data and operations that it receives. Used duringthe development process to monitor the behavior of a system in a givenpoint of its structure.

[7364] Input a terminal with incoming flow of control. As related toterminals, directional attributes such as incoming and outgoing arealways defined from the viewpoint of the object on which the terminal isdefined.

[7365] Interaction an act of transferring data, invoking an operation,passing an event, or otherwise transfer control between objects,typically on a single connection between two terminals.

[7366] Interaction, incoming in a context of a given object, aninteraction that transfers data, control or both data and control intothis object. Whenever both control and data are being transferred in oneand the same interaction, the direction is preferably determined by thedirection of the transfer of control.

[7367] Interaction, outgoing in a context of a given object, aninteraction that transfers data, control or both data and control out ofthis object. Whenever both control and data are being transferred in oneand the same interaction, the direction is preferably determined by thedirection of the transfer of control

[7368] Interface a specification for a set of related operations thatare implemented together. An object given access to an implementation ofan interface is guaranteed that all operations of the interface can beinvoked and will behave according to the specification of thatinterface.

[7369] Interface,

[7370] message-based an interface the operations of which are invokedthrough messages in message-passing systems. “Message-based” pertains toa physical mechanism of access in which the actual binding of therequested operation to code that executes this operation on a givenobject is performed at call time.

[7371] Interface, OLE COM a standard of defining interfaces specifiedand enforced by COM. Based on the virtual table dispatch mechanismsupported by C++ compilers.

[7372] Interface, remoting a term defined by Microsoft OLE COM to denotethe process of transferring operations invoked on a local implementationof an interface to some implementation running on a different computeror in a different address space, usually through an RPC mechanism.

[7373] Interface, v-table a physical mechanism of implementinginterfaces, similar to the one specified by OLE COM.

[7374] Marshaler a category of parts used to convert an interface whichis defined in the scope of a single address space to a logicallyequivalent interface on which the operations and related data can betransferred between address spaces.

[7375] Multiplexor a category of parts used to direct a flow ofoperations invoked on its input through one of several outgoingconnections. Multiplexors are used for conditional control of the eventflows in structures of interconnected parts.

[7376] Name a persistent identifier of an entity that is unique within agiven scope. Most often names are human-readable character strings;however, other values can be used instead as long as they arepersistent.

[7377] Name space the set of all defined names in a given scope.

[7378] Name space, joined a name space produced by combining the namespaces of several parts. Preferably used in the present invention toprovide unique identification of properties and terminals of parts in astructure that contains those parts.

[7379] Object, composite an object that includes other objects,typically interacting with each other. Composites usually encapsulatethe subordinate objects.

[7380] Output a terminal with outgoing flow of control. See also Input.

[7381] Parameterization a mechanism and process of modifying thebehavior of an object by supplying particular data values for attributesdefined by the object.

[7382] Part an object or a component preferably created through anabstract factory and having properties and terminals. Parts can beassembled into structures at run-time.

[7383] Property a named attribute of an object exposed for manipulationfrom outside through a mechanism that is not specific for this attributeor object class.

[7384] Property interface an interface which defines the set ofoperations to manipulate properties of objects that implement it.Typical operations of a property interface include: get value, setvalue, and enumerate properties.

[7385] Property mechanism a mechanism defining particular ways ofaddressing and accessing properties. A single property interface may beimplemented using different property mechanisms, as it happens withparts and assemblies. Alternatively, the same property mechanism can beexposed through a number of different property interfaces.

[7386] Proxy program code, object or component designed to present anentity or a system in a way suitable for accessing it from a differentsystem. Compare to a wrapper.

[7387] Repeater a category of parts used to facilitate connections incases where the number of required connections is greater than themaximum number supported by one or more of the participants.

[7388] Return status a standardized type and set of values returned byoperations of an interface to indicate the completion status of therequested action, such as OK, FAILED, ACCESS VIOLATION, etc.

[7389] Serialization part of a persistency mechanism in object systems.A process of storing the state of one or more objects to persistentstorage such as file, database, etc. See also de-serialization.

[7390] Structure of parts a set of parts interconnected in a meaningfulway to provide specific functionality.

[7391] Structured storage a mechanism for providing persistent storagein an object system where objects can access the storage separately andindependently during run-time.

[7392] Terminal a named entity defined on an object for the purposes ofestablishing connections with other objects.

[7393] Terminal, cardinality the maximum number of connections in whicha given terminal can participate at the same time. The cardinalitydepends on the nature of the connection and the way the particularterminal is implemented.

[7394] Terminal, exterior a terminal, preferably used to establishconnections between the part to which it belongs and one or more objectsoutside of this part.

[7395] Terminal, interior a terminal, of an assembly, preferably used toestablish connections between the assembly to which it belongs and oneor more subordinate objects of this assembly.

[7396] Terminal interface an interface which defines the set ofoperations to manipulate terminals of objects that implement it.

[7397] Terminal mechanism a mechanism defining particular ways ofaddressing and connecting terminals. A single terminal interface may beimplemented using different terminal mechanisms, as happens with partsand assemblies.

[7398] Thread of execution a unit of execution in which processorinstructions are being executed sequentially in a given executioncontext. In the absence of a multithreaded operating system or kernel,and when interrupts are disabled, a single-processor system has only onethread of execution, while a multiprocessor system has as many threadsof execution as it has processors. Under the control of a multithreadedoperating system or kernel, each instance of a system thread objectdefines a separate thread of execution.

[7399] Wrapper program code, object or component designed to present anentity or a system in a way suitable for inclusion in a differentsystem. Compare to a proxy.

What is claimed is:
 1. A method for designing a software system in whichsystem at least a first object is created arbitrarily earlier than asecond object and said second object is automatically connected to atleast said first object, said method comprising the steps of: creatingsaid first object; creating a first container object capable of holdingat least one other object of arbitrary object class; defining at least afirst template connection between said first object and said firstcontainer object; creating said second object; connecting said secondobject to said first object using said first template connection inwhich template said first container object is replaced with said secondobject.
 2. The method in claim 1 wherein the step of creating saidsecond object is performed by said first container object.
 3. The methodin claim 1 wherein the step of connecting said second object to saidfirst object is performed by said first container object.
 4. The methodin claim 1 wherein the step of creating said second object is performedby said first container object and the step of connecting said secondobject to said first object is performed by said first container object.5. The method in claim 1 wherein connections between all objects areestablished between connection points on said objects.
 6. The method inclaim 1 wherein said first template connection is defined in a datastructure.
 7. The method in claim 5 wherein said first templateconnection is defined in a data structure.
 8. A system created using anyone of claims 1, 2, 3, 4, 5, 6 or
 7. 9. A method for describingconnections between a plurality of objects in a software system in whichat least a first object of said plurality is created arbitrarily laterthan the remainder of said plurality, said method comprising the stepsof: defining at least a second object of said remainder; defining afirst container object which will be used as a placeholder for definingconnections between said first object and said remainder; defining atleast a first connection between said second object and said firstobject by using said first container object in place of said firstobject.
 10. A method for describing connections between a firstplurality of objects in a software system and a second plurality ofobjects in said software system, said second plurality being createdarbitrarily later than said first plurality, said method comprising thesteps of: defining at least a first object of said first plurality;defining a first container object which will be used as a placeholderfor defining connections between said first object and each object ofsaid second plurality; defining at least a first connection to becreated between said first object and each object of said secondplurality as a connection between said first object and said firstcontainer object.
 11. In a software system, said software system havinga plurality of objects, a container object comprising: a first memoryfor keeping reference to at least a first object of arbitrary objectclass; a section of program code causing said first memory to bemodified so that it will contain a first reference to a second object; asection of program code accessing a data structure and determining thatat least a first connection needs to be established between said secondobject and at least a third object; a section of program code causingsaid first connection to be established.
 12. The container object ofclaim 10 further comprising a section of program code causing saidsecond object to be created.
 13. In a software system, said softwaresystem having a plurality of objects, a container object comprising: amemory for keeping at least one reference to a contained object ofarbitrary class; a connection point for receiving requests to modify theset of contained objects; at least one virtual connection point thataccepts at least a first connection to be established to said containedobject, said acceptance occurring before said contained object is addedto said contained object; a section of program code that establishessaid first connection when said contained object is added to saidcontainer object.
 14. In a software system, said software system havinga plurality of objects, a container object comprising: a first memoryfor keeping at least one reference to a contained object of arbitraryclass; a connection point for receiving requests to modify the set ofcontained objects; at least one virtual property that accepts the valueto be set in a first property on said contained object, said virtualproperty being capable of accepting values of a plurality of data types;a section of program code that sets said first property on saidcontained object to said accepted value when said contained object isadded to said contained object.
 15. In a software system, said softwaresystem having a plurality of objects, a container object comprising: afirst memory for keeping a first plurality of contained objects ofarbitrary classes; a second memory for keeping a second plurality ofunique identifiers, each identifier of said second plurality associatedwith exactly one object of said first plurality; at least a firstproperty, said first property being a second property of a first objectof said first plurality and said first property being identified by acombined identifier produced by combining the associated identifier ofsaid first object and the identifier of said second property.
 16. Thesoftware system of claim 15, wherein each said property comprises aterminal.
 17. The software system of either of claims 15 or 16, whereinthe second memory doesn't exist and contained objects are identified byidentifiers assigned by the container.
 18. A container object class in asoftware system, said software system having a first plurality ofobjects, each object of said first plurality belonging to an objectclass, said container object class comprising: means for holding asecond plurality of contained objects, said means being applicable tocontained objects of any class; means for changing the set of saidcontained objects, said means being applicable to contained objects ofany class; means for presenting said plurality of contained objects as asingle object, said means being applicable to contained objects of anyclass.
 19. The container object class of claim 18 wherein said singleobject is an instance of said container object class.
 20. A containerobject which is an instance of the container object class of claim 18.21. In a software system, said software system having a plurality ofobjects, each object of said plurality of objects belonging to an objectclass, said software system having means for building at least onestructure of connected objects and means of describing said structure ofconnected objects, a container object class comprising: means forholding a plurality of contained objects, said means being applicable tocontained objects of any class; means for changing the set of saidcontained objects programmatically, said means being applicable tocontained objects of any class; means for presenting said plurality ofcontained objects as a single object in said structure of connectedobjects, said means being applicable to contained objects of any class.22. A container object which is an instance of the container objectclass of claim
 21. 23. In a software system having at least a firstobject and a second object, said first object having at least one firstconnection point, said second object having at least one secondconnection point, said first connection point being used to establish afirst connection between said first connection point of said firstobject and said second connection point of said second object, and saidsoftware system having means of requesting the establishment of aconnection between connection points, a container object comprising:means for adding and removing said first object from said container;means for defining a third connection point on said container object;means for transforming a requests for establishing of a connectionbetween said second connection point and said third connection pointinto a request for establishing a connection between said secondconnection point and said first connection point.
 24. The containerobject of claim 23 wherein said software system includes means ofidentifying said first connection point using a first identifier, saidcontainer object having the additional means to identify said thirdconnection point using said first identifier.
 25. The container objectof claim 23 wherein said software system includes means of identifyingsaid first connection point using a first identifier, said containerobject having the additional means to identify said first object using asecond identifier and said container object having the additional meansto identify said third connection point using a combination of saidfirst identifier and said second identifier.
 26. A container object in asoftware system, said software system having at least one first objectand said container object, said first object having at least one firstproperty, said software system having means of requesting operationsover said first property, said container comprising: means for addingand removing said first object from said container; means for defining asecond property on said container object; means for transforming arequest for operations over said second property into a request foroperations over said first property.
 27. The container object of claim26 wherein said software system has means of identifying said firstproperty using a first identifier, said container object having theadditional means to identify said second property using said firstidentifier.
 28. The container object of claim 26 wherein said softwaresystem has means of identifying said first property using a firstidentifier, said container object having the additional means toidentify said first object using a second identifier and said containerobject having the additional means to identify said second propertyusing a combination of said first identifier and said second identifier.29. A container object having the sum of the means of the containerobject of claim 25 and of the container object of claim
 28. 30. Thecontainer of claim 29 wherein all the specified means of said containerare implemented independently of the class of said first object.
 31. Acontainer object in a software system, said software system having aplurality of objects, said software system having means for requestingoperations over an object, said container object comprising: means forholding a plurality of contained objects; means for changing the set ofsaid contained objects programmatically; means for identifying eachobject of said contained objects by a separate, unique identifier foreach object; means of handling requests for operations over any objectof said contained objects wherein said identifier is used to determinewhich object of said contained objects should handle the request. 32.The container of claim 31 wherein said container has the additionalmeans of automatically assigning said unique identifier to each objectadded to said container.
 33. The container of claim 31 wherein saidunique identifier is assigned outside of said container, and saidcontainer has the additional means of associating said unique identifierwith each said contained object.
 34. A method for caching andpropagating property values to a dynamic set of objects in a softwaresystem, said software system having a plurality of objects, each of saidobjects having a plurality of properties, each said property having avalue and an identifier, said method comprising the steps of: acceptinga first request to modify the value of a first property on behalf ofsaid dynamic set of objects as if said dynamic set of objects were oneobject; storing said value and identifier of said first property in afirst data storage; retrieving said value and identifier of said firstproperty from said first data storage; issuing a request to modify thevalue of said first property on a first object of said dynamic set ofobjects, using said value and identifier retrieved from said first datastorage.
 35. A container object in a software system using the method inclaim
 34. 36. A method for caching and propagating outgoing connectionsof a dynamic set of objects in a software system, said software systemhaving a plurality of objects, said software system having means forestablishing connections between said objects, said connectionsproviding means for a first connected object to make outgoing calls to asecond connected object, said method comprising the steps of: acceptingthe request to establish a first outgoing connection between saiddynamic set of objects and a first object, as if said dynamic set ofobjects were a single object; storing a first data value necessary toeffect said first connection in a first data storage; retrieving saidfirst data value from said first data storage; issuing a request toestablish a second connection between a second object of said dynamicset and said first object, using said first data value retrieved fromsaid first data storage.
 37. A container object in a software systemusing the method in claim
 36. 38. A container object in a softwaresystem using both the method in claim 34 and the method in claim
 36. 39.A container object in a software system, said software system having aplurality of objects, said software system having means for building atleast one structure of connected objects, said software system having afirst means of describing said structure, said container object being afirst object in said structure, said first object having a firstconnection to at least a second object in said structure, said firstconnection being described by said first means, said containercomprising: means for holding a plurality of contained objects; meansfor changing the set of said contained objects programmatically; meansfor connecting each of said contained objects to said second object. 40.The container in claim 39 wherein said container has the additionalmeans of establishing all connections between said container and otherobjects in said structure, said all connections being described by saidfirst means, said additional means causing the establishing of each ofsaid all connections between each of said contained objects and saidother objects in said structure.
 41. A container object in a softwaresystem, said software system having a plurality of objects, saidsoftware system having means of building at least one structure ofconnected objects, said software system having a first means ofdescribing said structure, said software system providing a second meansof enumerating all connections described by said first means, saidcontainer being a first object in said structure, said container beingconnected to at least a second object in said structure, said containercomprising: means for holding a plurality of contained objects; meansfor changing the set of said contained objects programmatically; meansfor finding a first described connection between said container and saidsecond object; means for establishing said first connection between athird object contained in said container and said second object.
 42. Thecontainer in claim 41 wherein said container establishes connectionsbetween a first connection point of said third object and a secondconnection point of said second object.
 43. A container object in asoftware system, said software system having a plurality of objects,said container having a first connection to at least one object, saidfirst connection being described in a first data structure, saidcontainer comprising: means for holding a plurality of containedobjects; means for changing the set of said contained objectsprogrammatically; means for determining a first set of connections to beestablished for each object added to said set of contained objects basedon the set of connections described in said first data structure; meansfor establishing said first set of connections.
 44. The container inclaim 43 wherein said container further comprises means for dissolvingsaid first set of connections.
 45. The container in claim 43 whereinsaid container further comprises: means for remembering a second set ofoutgoing connections from said container to other objects means forexcluding said second set of connections from said first set ofconnections means for establishing said second set of outgoingconnections for each object added to said set of contained objects. 46.The container in claim 43 wherein said container further comprises:means for remembering properties set on said container; means forsetting remembered properties on each new object added to said set ofcontained objects; means for propagating properties set on saidcontainer to all objects in said set of contained objects;
 47. Acontainer object in a software system, said software system containing aplurality of objects, said software system having a first means toestablish connections between connection points of objects of saidplurality, said first means providing the ability to establish more thanone connection to a first connection point of a first object, saidcontainer object having a second connection point connected to saidfirst connection point of said first object, said container comprising:means for holding a plurality of contained objects; means for changingthe set of said contained objects programmatically; means forestablishing a separate connection between a connection point on eachobject of said plurality of contained objects and said first connectionpoint of said first object.
 48. The container in claim 43 wherein saidcontainer further comprises: means for remembering properties set onsaid container;
 49. A part for distributing events among a plurality ofparts, said part comprising: a multiple cardinality input, a multiplecardinality output, means for recording references to parts that areconnected to said output means for forwarding events received on saidinput to each of the connected objects to said output.
 50. A part fordistributing events and requests between a plurality of other parts,said part comprising: a first terminal for receiving calls; a secondterminal for sending calls out to a first connected part; a thirdterminal for sending calls out to a second connected part; means forchoosing whether to send the received call through said second terminalor through said third terminal.
 51. A part for distributing events andrequests between a plurality of other parts, said part comprising: afirst terminal for receiving calls; a second terminal for sending callsout to a first connected part; a third terminal for sending calls out toa second connected part; means for choosing whether to first send thereceived call through said second terminal and then through said thirdterminal or to first send the received call through said third terminaland then through said second terminal.
 52. A part for distributingevents and requests between a plurality of other parts, said partcomprising: a first terminal for receiving calls; a second terminal forsending calls out to a first connected part; a third terminal forsending calls out to a second connected part; means for sending a firstreceived call as a first call to said second terminal and then, based onvalue returned from said first call, choose whether or not to send saidfirst received call as a second call to said third terminal.
 53. Amethod for desynchronizing events and requests in a software system,said method comprising the steps of: storing said event in a memory;receiving a pulse signal; retrieving said event from said memory andcontinuing to process said event in the execution context of said pulsesignal.
 54. A part in a software system, said part comprising: a firstterminal for receiving calls; a second terminal for sending calls out toa first connected part; a third terminal for receiving a pulse call; amemory for storing call information received from said first terminal; asection of program code that is executed when said part receives saidpulse calls, said section retrieving said call information from saidmemory and sending a call out to said second terminal.
 55. The part inclaim 54 wherein said memory can hold call information for a pluralityof calls.
 56. The part in claim 54 wherein said memory is a queue. 57.The part in claim 54 wherein said memory is a stack.
 58. The part inclaim 54 wherein said first terminal and said second terminal are oneterminal.
 59. A part in a software system, said part comprising: a firstterminal for receiving calls; a second terminal for sending calls out tofirst connected part; a memory for storing call information receivedfrom said first terminal; a means for obtaining execution context; asection of program code that is executed in said execution context, saidsection retrieving said call information from said memory and sending acall out to said second terminal.
 60. The part in claim 59 wherein saidmeans for obtaining execution context is a thread of execution in amultithreaded system.
 61. The part in claim 59 wherein said means forobtaining execution context is a timer callback.
 62. The part in claim59 wherein said means for obtaining execution context is a subordinatepart.
 63. The part in claim 59 wherein said means for obtainingexecution context is a subordinate part, said subordinate part having aprimary function of providing execution context for other parts.
 64. Thepart in claim 59 wherein said first terminal and said second terminalare one terminal.
 65. A part in a software system, said part comprising:a first subordinate part for storing incoming data; a second subordinatepart for generating execution context.
 66. The part in claim 65 whereinsaid part further comprises a connection between said first subordinatepart and said second subordinate part.
 67. A part in a software system,said part comprising: a first terminal for receiving an incomingrequest; a second terminal for sending out an outgoing request; a thirdterminal for receiving a request completion indication; asynchronization object for blocking the thread in which said incomingrequest was received until said request completion indication isreceived.
 68. The part in claim 67 wherein said second terminal and saidthird terminal are one terminal.
 69. A part in a software system, saidpart comprising: an input terminal for receiving calls of a first type;an output terminal for sending calls of a second type; means forconverting calls of said first type to calls of said second type.
 70. Apart in a software system, said part comprising: an input terminal forreceiving calls of a first type and sending calls of said first type; anoutput terminal for receiving calls of a second type and sending callsof said second type; means for converting calls of said first type tocalls of said second type; means for converting calls of said secondtype to calls of said first type.
 71. The part of claim 70 wherein saidfirst type and said second type differ by physical mechanism.
 72. Thepart of claim 70 wherein said first type and said second type differ bylogical contract.
 73. A part in a software system, said part comprising:a first terminal for receiving a first request and sending a secondrequest; a second terminal for sending said first request; a thirdterminal for receiving said second request.
 74. The part of claim 73wherein: said first terminal is a bidirectional terminal; said secondterminal is an output terminal; said third terminal is an inputterminal.
 75. A part in a software system, said part comprising: a firstterminal for receiving calls; a second terminal for sending out callsreceived on said first terminal; a third terminal for sending out callswhenever a call is received on said first terminal.
 76. The part inclaim 76 wherein said part further comprises a first property fordefining a criterion for selecting for which calls received on saidfirst terminal said part will send out calls through said thirdterminal.
 77. The part in claim 76 wherein said part further comprises asecond property for configuring what call said part will send out saidthird terminal.
 78. The part in claim 76 wherein said part furthercomprises a third property for configuring what call said part will sendout said third terminal before sending out a call received on said firstterminal to said second terminal.
 79. The part in claim 76 wherein saidpart further comprises a third property for configuring what call saidpart will send out said third terminal after sending out a call receivedon said first terminal to said second terminal.
 80. The part in claim 76wherein said part further comprises a third property for configuringwhether a call out through said third terminal should be made before orafter sending out a call received on said first terminal to said secondterminal.
 81. A part in a software system, said part comprising: a firstterminal for receiving calls; a second terminal for sending out callsreceived on said first terminal; a third terminal for sending out callswhenever a call sent out said second terminal returns a pre-determinedvalue.
 82. The part of claim 81 wherein said part further comprises aproperty for configuring said pre-determined value.
 83. The part ofclaim 81 wherein said pre-determined value indicates that said secondcall has failed.
 84. The part of claim 81 wherein said pre-determinedvalue indicates that said second call has succeeded.
 85. A part in asoftware system, said part comprising: a first terminal for receivingcalls; a second terminal for sending out calls received on said firstterminal; a first property for configuring a first value; a thirdterminal for sending out notification calls whenever a call sent outsaid second terminal returns a second value that matches said firstvalue.
 86. The part of claim 85 wherein said part further comprises asecond property for configuring whether said part will send out saidnotification calls if said second value matches said first value or ifsaid second value differs from said first value.
 87. A part in asoftware system, said part comprising: a terminal for receiving calls ofarbitrary logical contract; a property for defining a return value. 88.The part of claim 87 wherein said part further comprises a property forconfiguring the logical contract for calls received on said terminal.89. The part of claim 87 wherein said terminal is an input terminal. 90.The part of claim 87 wherein said terminal is a bidirectional terminaland said part does not make calls out said terminal.
 91. A part in asoftware system, said part comprising: a terminal for receiving a firstcall and a reference to a first memory; a property for defining a returnvalue; a section of program code for freeing said first memory.
 92. Thepart in claim 91 wherein said part further comprises means fordetermining whether said section of program code should be executed forsaid first call.
 93. The part in claim 91 wherein said part furthercomprises means for determining whether said section of program codeshould be executed for said first call based on a value contained insaid first memory.
 94. A part in a software system, said partcomprising: a first terminal for receiving a first call; a secondterminal for sending out said first call; means for extracting data fromsaid first call; means for formatting said extracted data as a firsttext; means for sending out said first text.
 95. The part of claim 94wherein said means for sending out said first text is a third terminal.96. The part of claim 94 wherein said means for sending out said firsttext is a section of program code that invokes a function for displayingsaid first text on a console.
 97. A first structure of connected partsin a software system, said first structure comprising: a factory partfor determining when a new part should be created; a container part forholding a first plurality of parts of arbitrary part class; a connectionbetween said factory part and said container part.
 98. The structure ofclaim 97 wherein: said factory part has a first terminal; said containerpart has a second terminal; said connection is established between saidfirst terminal and said second terminal.
 99. The structure of claim 97wherein said structure further comprises a demultiplexing part having afirst terminal for receiving calls, a second terminal for sending outcalls and means for selecting a part connected to said second terminal.100. The structure of claim 99 wherein said structure further comprisesa plurality of connections, each connection established between saidsecond terminal of said demultiplexing part and a terminal of each partin said first plurality.
 101. The structure of claim 100 wherein saidconnection demultiplexing part and said factory part are one part. 102.A composite part in a software system, said composite part comprisingthe structure in claim
 97. 103. The structure of claim 97 wherein saidstructure further comprises an enumerator part for defining the set ofparts in said first plurality.
 104. The structure of claim 103 whereinsaid structure further comprises a connection between said enumeratorpart and said factory part.
 105. The structure of claim 97 wherein saidenumerator uses a data container for defining the parts in firstplurality.
 106. The structure of claim 103 wherein said enumeratorcomprises means for enumerating a set of peripheral devices connected toa computer system.
 107. The structure of claim 106 wherein saidenumerator further comprises a first property for configuring alimitation on the type of peripheral devices to be enumerated.
 108. Thestructure of claim 97 wherein said structure further comprises aparameterizer part for retrieving the value for at least one property tobe set on each part of said first plurality.
 109. The structure of claim108 wherein said parameterizer part retrieves said value from a datacontainer.
 110. The structure of claim 108 wherein said parameterizerpart uses a persistent identifier to select said value among a set ofvalues.
 111. The structure of claim 97 wherein said structure furthercomprises a serializer part for saving the value of at least on propertyof each part in said first plurality.
 112. The structure of claim 111wherein said structure further comprises a trigger part for initiatingsaid saving of the value.
 113. The structure of claim 97 wherein saidstructure further comprises a parameterizer part for retrieving thevalue for a first property to be set on each part of said firstplurality and for saving the value of said first property.
 114. Thestructure of claim 97 wherein said factory part determines whether tocreate a new part in said first plurality or to use an existing part insaid first plurality based a persistent identifier provided to saidfactory part.
 115. The structure of claim 97 wherein said structurefurther comprises a loader part for bringing in memory a class for apart to be created.
 116. The structure of claim 116 wherein saidstructure further comprises: a connection between said factory part andsaid loader part; a connection between said loader part and saidcontainer part.
 117. A part in a software system, said part comprising:a first terminal for receiving calls; a second terminal for sending outcalls received on said first terminal; a third terminal for sending outrequests to create new parts; means for selecting calls received on saidfirst terminal for which said part sends out requests on said thirdterminal.
 118. A method for designing access to a hardware component ina component-based software system, said method comprising the steps of:designating a first software component for receiving interrupts fromsaid hardware component; designating a at least a second softwarecomponent for accessing input and output ports of said hardwarecomponent; designating a third software component for handlinginterrupts received by said first software component; designating afourth software component for manipulating said hardware component;connecting said first software component to said third softwarecomponent; connecting said second software component to said fourthsoftware component.
 119. The method in claim 118 wherein said methodfurther comprises the step of connecting said third software componentand said fourth software component.
 120. The method in claim 118 whereinsaid third software component and said fourth software component are onecomponent.
 121. A part in a software system, said part comprising: afirst terminal for sending out calls; a section of program code forreceiving control when an interrupt occurs and sending out a callthrough said first terminal.
 122. The part of claim 121 wherein saidpart further comprises a property for configuring which hardwareinterrupt vector among a plurality of hardware interrupt vectors saidpart should receive.
 123. The part of claim 121 wherein said partfurther comprises a section of program code for registering said part toreceive control when said interrupt occurs.
 124. A part in a softwaresystem, said part comprising: a terminal for receiving requests toaccess at least one port of a hardware component; a property definingthe base address of said port; a section of code that accesses said portwhen a request is received on said first terminal.
 125. The part ofclaim 124 wherein said port is a memory-mapped port.
 126. The part ofclaim 124 wherein said port is a input-output port.
 127. The part ofclaim 124 wherein said requests include a read request and a writerequest.
 128. A structure of connected parts in a software system, saidstructure comprising: an interrupt source part for receiving interruptfrom a hardware component; at least one port accessor part for accessingports of said hardware component; at least one controller part forcontrolling said hardware component.
 129. The structure of claim 128wherein said controller part accesses said hardware componentexclusively through said interrupt source part and said port accessorpart.
 130. The structure of claim 128 wherein said structure furthercomprises: a connection between said interrupt source part and one ofsaid controller parts; a connection between one of said port accessorparts and one of said controller parts.
 131. A composite part in asoftware system, said composite part containing the structure of claim128.
 132. A composite part in a software system, said composite partcontaining the structure of claim
 129. 133. A method for designingsoftware system in which system at least a first object is createdarbitrarily earlier than a second object and said second object isautomatically connected to at least said first object, said methodcomprising the steps of: creating said first object; creating a firstcontainer object capable of holding at least one other object ofarbitrary object class; defining at least a first template connectionbetween said first object and said first container object; creating saidsecond object; connecting said second object to said first object usingsaid first template connection in which template said first containerobject is replaced with said second object